Пример #1
0
 AdiDeviceResult AdiDevice::Read(ADI_DEV_BUFFER_TYPE bufferType, 
     ADI_DEV_BUFFER *pBuffer) 
 {
     ESS_ASSERT(IsOpened());
     
     return adi_dev_Read(m_deviceHandle, bufferType, pBuffer);
 }
Пример #2
0
static void Callback(
	void *AppHandle,
	u32  Event,
	void *pArg)
{
	
	ADI_DEV_1D_BUFFER *pBuffer;			// pointer to the buffer that was processed
	
	// CASEOF (event type)
	switch (Event) {
		
		// CASE (buffer processed)
		case ADI_DEV_EVENT_BUFFER_PROCESSED:
		
			// identify which buffer is generating the callback
			// we're setup to only get callbacks on inbound buffers so we know this 
			// is an inbound buffer
			pBuffer = (ADI_DEV_1D_BUFFER *)pArg;

			if (pArg == &InboundBuffer)
			{ 

		    	InputBuffer[InputBufferhead] = InboundData;
				InputBufferhead = (InputBufferhead +1) % INBUFLEN;
			    
				if ((InputBufferhead +1) % INBUFLEN != InputBuffertail)
				
				// requeue the inbound buffer
				ezErrorCheck(adi_dev_Read(DriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)&InboundBuffer));
			}
			else if (pArg == &OutboundBuffer)
			{
			    sending_done = 1;
			}
			break;
			
		// CASE (an error)
		case ADI_UART_EVENT_BREAK_INTERRUPT:
			ezErrorCheck(ADI_UART_EVENT_BREAK_INTERRUPT);
			break;
		case ADI_UART_EVENT_FRAMING_ERROR:
			ezErrorCheck(ADI_UART_EVENT_FRAMING_ERROR);
			break;
		case ADI_UART_EVENT_PARITY_ERROR:
			ezErrorCheck(ADI_UART_EVENT_PARITY_ERROR);
			break;
		case ADI_UART_EVENT_OVERRUN_ERROR:
			ezErrorCheck(ADI_UART_EVENT_OVERRUN_ERROR);
			break;
			
	// ENDCASE
	}
	
	// return
}
Пример #3
0
void UARTinit( u32 baudrate )
{
    ADI_DCB_HANDLE			DCBManagerHandle = 0;		// handle to the callback service
	u32 cclk, sclk, vco;							// frequencies (note these are in MHz)
	u32 i; 											//loop variable
	
	ADI_DEV_CMD_VALUE_PAIR ConfigurationTable [] = {	// configuration table for the UART driver
		{ ADI_DEV_CMD_SET_DATAFLOW_METHOD, 	(void *)ADI_DEV_MODE_CHAINED	},
		{ ADI_UART_CMD_SET_DATA_BITS, 		(void *)8						},
		{ ADI_UART_CMD_ENABLE_PARITY, 		(void *)FALSE					},
		{ ADI_UART_CMD_SET_STOP_BITS, 		(void *)1						},
		{ ADI_UART_CMD_SET_BAUD_RATE, 		(void *)baudrate				},
		{ ADI_UART_CMD_SET_LINE_STATUS_EVENTS, 	(void *)TRUE					},
		{ ADI_DEV_CMD_END,					NULL							},
	};
	
	InputBufferhead = 0;
	InputBuffertail = 0;
	
	// create two buffers that will be initially be placed on the inbound queue
	// only the inbound buffer will have a callback
	InboundBuffer.Data = &InboundData;
	InboundBuffer.ElementCount = 1;
	InboundBuffer.ElementWidth = 1;
	InboundBuffer.CallbackParameter = (void*)&InboundBuffer;
	InboundBuffer.ProcessedFlag = FALSE;
	InboundBuffer.pNext = NULL;
	
	sending_done = 1;
	OutboundBuffer.Data = OutboundData;
	OutboundBuffer.ElementCount = 1;
	OutboundBuffer.ElementWidth = 1;
	OutboundBuffer.CallbackParameter = (void*)&OutboundBuffer;
	OutboundBuffer.ProcessedFlag = TRUE;
	OutboundBuffer.pNext = NULL;

	// open the UART driver for bidirectional data flow
	ezErrorCheck(adi_dev_Open(DeviceManagerHandle, &ADIUARTEntryPoint, 0, NULL, &DriverHandle, ADI_DEV_DIRECTION_BIDIRECTIONAL, NULL, DCBManagerHandle, Callback));
		
	// configure the UART driver with the values from the configuration table
   	ezErrorCheck(adi_dev_Control(DriverHandle, ADI_DEV_CMD_TABLE, ConfigurationTable));
		
	// give the device the inbound buffer
	ezErrorCheck(adi_dev_Read(DriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)&InboundBuffer));

	// enable data flow
	ezErrorCheck(adi_dev_Control(DriverHandle, ADI_DEV_CMD_SET_DATAFLOW, (void *)TRUE));	
	
}
Пример #4
0
static u32 adi_pdd_Read(		// Reads data or queues an inbound buffer to a device
	ADI_DEV_PDD_HANDLE 	PDDHandle,	// PDD handle
	ADI_DEV_BUFFER_TYPE	BufferType,	// buffer type
	ADI_DEV_BUFFER 		*pBuffer	// pointer to buffer
){
	// check for errors if required
	u32 Result = ADI_DEV_RESULT_SUCCESS;
#if defined(ADI_DEV_DEBUG)
	if ((Result = ValidatePDDHandle(PDDHandle)) != ADI_DEV_RESULT_SUCCESS) return (Result);
#endif
	// Simply pass the request on
	ADI_AD7477A *pAD7477A = (ADI_AD7477A *)PDDHandle;
	Result = adi_dev_Read(pAD7477A->spiHandle,BufferType,pBuffer);

	return(Result);
}
Пример #5
0
static u32 adi_pdd_Read(							// Reads data or queues	an inbound buffer to a device
	ADI_DEV_PDD_HANDLE		PDDHandle,				// PDD handle
	ADI_DEV_BUFFER_TYPE		BufferType,				// buffer type
	ADI_DEV_BUFFER			*pBuffer				// pointer to buffer
) {
	//	Pointer	to ADAV801 device driver instance	
	ADI_ADAV801	 *pADAV801 = (ADI_ADAV801 *)PDDHandle;	

#ifdef ADI_DEV_DEBUG
	// check for errors	if required
	u32	Result = ADI_DEV_RESULT_SUCCESS;
 	if	((Result = ValidatePDDHandle(PDDHandle)) !=	ADI_DEV_RESULT_SUCCESS)	return (Result);
#endif
	
	// pass	read operation to SPORT
	return(adi_dev_Read(pADAV801->sportHandle,BufferType,pBuffer));

}
Пример #6
0
u8 UARTread()
{
	u8 data;
	
	while (!UARThit());
	
	data = InputBuffer[InputBuffertail];
	InputBuffertail = (InputBuffertail +1) % INBUFLEN;
	
	if (InboundBuffer.ProcessedFlag == 1)
	{
	    InboundBuffer.ProcessedFlag = 0;
	
		// requeue the inbound buffer
		ezErrorCheck(adi_dev_Read(DriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)&InboundBuffer));
	}
		
	return data;
}
Пример #7
0
/*********************************************************************

    Function: adi_ad1980_SportConfig

        Opens and Configures SPORT device allocated to AD1980 Audio Codec

    Parameters:
        poDevice         - Pointer to AD1980 device instance to work on

    Returns:
        ADI_DEV_RESULT_SUCCESS
            - Successfully opened and configured SPORT device
        Error code returned from SPORT driver

*********************************************************************/
static u32 adi_ad1980_SportConfig(
    ADI_AD1980_DEF          *poDevice
)
{

    /* default return code */
    u32     nResult = ADI_DEV_RESULT_SUCCESS;

    /* SPORT Configuration Table */
    ADI_DEV_CMD_VALUE_PAIR  aoSportConfigTable[] =
    {
        /* clear any previous Tx errors */
        { ADI_SPORT_CMD_CLEAR_TX_ERRORS,    (void *)NULL                    },
        /* clear any previous Rx errors */
        { ADI_SPORT_CMD_CLEAR_RX_ERRORS,    (void *)NULL                    },
        /* SPORT in Circular mode       */
        { ADI_DEV_CMD_SET_DATAFLOW_METHOD,  (void *)ADI_DEV_MODE_CIRCULAR   },
        /* Enable Streaming mode        */
        { ADI_DEV_CMD_SET_STREAMING,        (void *)true                    },
        /* External Frame sync, MSB first, No TFS required  */
        { ADI_SPORT_CMD_SET_TCR1,           (void *)0                       },
        /* Secondary disabled   */
        { ADI_SPORT_CMD_SET_TCR2,           (void *)0                       },
        /* Tx Wordlength = 16 bits  */
        { ADI_SPORT_CMD_SET_TX_WORD_LENGTH, (void *)15                      },
        /* Internal RFS, Require RFS for every data */
        { ADI_SPORT_CMD_SET_RCR1,           (void *)0x0600                  },
        /* Secondary disabled   */
        { ADI_SPORT_CMD_SET_RCR2,           (void *)0                       },
        /* Rx Wordlength = 16 bits  */
        { ADI_SPORT_CMD_SET_RX_WORD_LENGTH, (void *)15                      },
        /* sets RFS to 48kHz (BIT_CLK for AC'97 = 12.288MHz) */
        { ADI_SPORT_CMD_SET_RFSDIV,         (void *)0xFF                    },
        /* MFD = 1, Enable Multi Channel, Enable Tx/Rx DMA packing */
        { ADI_SPORT_CMD_SET_MCMC2,          (void *)0x101C                  },
        /* 16 Channels */
        { ADI_SPORT_CMD_SET_MTCS0,          (void *)0xFFFF                  },
        /* 16 Channels */
        { ADI_SPORT_CMD_SET_MRCS0,          (void *)0xFFFF                  },
        /* Window Size = ((16 Channels/8) - 1) = 1 */
        { ADI_SPORT_CMD_SET_MCMC1,          (void *)0x1000                  },
        /* Enable error reporting */
        { ADI_DEV_CMD_SET_ERROR_REPORTING,  (void *)true                    },
        /* End of Configuration table */
        { ADI_DEV_CMD_END,                  (void *)NULL                    },
    };

    /* IF (Reset Flag ID is valid) */
    if (poDevice->eResetFlag != ADI_FLAG_UNDEFINED)
    {
        /* Issue a Hardware reset to AD1980 */
        nResult = adi_ac97_HwReset(poDevice->pAC97, poDevice->eResetFlag);
    }
    /* ELSE (Invalid reset flag) */
    else
    {
        /* Report failure (Invalid Reset Flag) */
        nResult = ADI_AD1980_RESULT_RESET_FLAG_ID_INVALID;
    }

    /* IF (Successfully Reset AD1980) */
    if (nResult == ADI_DEV_RESULT_SUCCESS)
    {
        /* Open SPORT Device connected to AD1980 */
        nResult = adi_dev_Open(poDevice->hDeviceManager,
                               &ADISPORTEntryPoint,
                               poDevice->nSportDevNumber,
                               poDevice,
                               &poDevice->hSport,
                               ADI_DEV_DIRECTION_BIDIRECTIONAL,
                               poDevice->hDmaManager,
                               NULL,
                               adi_ad1980_SportCallback);
    }

    /* IF (Successfully opened SPORT device) */
    if (nResult == ADI_DEV_RESULT_SUCCESS)
    {
        /* Configure SPORT Device */
        nResult = adi_dev_Control(poDevice->hSport,
                                  ADI_DEV_CMD_TABLE,
                                  (void *)&aoSportConfigTable[0]);
    }

    /* IF (Successfully Configured the SPORT driver) */
    if (nResult == ADI_DEV_RESULT_SUCCESS)
    {
        /* Submit outbound buffer */
        nResult = adi_dev_Write (poDevice->hSport,
                                 ADI_DEV_CIRC,
                                 (ADI_DEV_BUFFER *)(&poDevice->pAC97->DacCircBuf));
    }

    /* IF (Successfully Submitted outbound buffer) */
    if (nResult == ADI_DEV_RESULT_SUCCESS)
    {
        /* Submit inbound buffer */
        nResult = adi_dev_Read (poDevice->hSport,
                                ADI_DEV_CIRC,
                                (ADI_DEV_BUFFER *)(&poDevice->pAC97->AdcCircBuf));
    }

    /* IF (Successfully Opened and Configured SPORT Device) */
    if (nResult == ADI_DEV_RESULT_SUCCESS)
    {
        /* Enable SPORT dataflow - this enables AC-Link to AD1980 */
        nResult = adi_dev_Control(poDevice->hSport,
                                  ADI_DEV_CMD_SET_DATAFLOW,
                                  (void *)true);
    }

    return (nResult);
}
Пример #8
0
/*##########################################################################
 *
 * low_level_init
 *
 *#########################################################################*/
static void
low_level_init(struct netif *netif)
{
  ADI_ETHER_BUFFER* p;
  struct nifce_info* nip = (struct nifce_info*)netif->state;
  struct buffer_info* bip;
  int rx_len, tx_len, count;
  int i;
  ADI_ETHER_BUFFER* rx_head = NULL;
  ADI_ETHER_BUFFER* tx_head = NULL;
  unsigned int *mangle_ptr;
  struct tcpip_msg* msg;

  LWIP_ASSERT("low_level_init: nfice info supply failed", nip != NULL);
  LWIP_ASSERT("low_level_init: buffer area supply failed",
              nip->buff_area != NULL && nip->buff_area_size > 0);

  // copy individual (MAC) address into netif struct
  for (i = 0; i < 6; i += 1)
    netif->hwaddr[i] = nip->ia[i];
  netif->hwaddr_len = 6;

  // calculate total requirement for each rx and tx buffer
  rx_len =  sizeof(ADI_ETHER_BUFFER) + sizeof(struct buffer_info);
  tx_len = rx_len;
  rx_len += nip->rx_buff_datalen + nip->buff_overhead;
  tx_len += nip->tx_buff_datalen + nip->buff_overhead;
  rx_len = ((rx_len + 3) / 4) * 4;
  tx_len = ((tx_len + 3) / 4) * 4;
  
  rx_len = (rx_len + 31) & ~31;
  tx_len = (tx_len + 31) & ~31;

   nip->buff_area = (char*)(((unsigned int)nip->buff_area + 31) & ~31);

  // allocate buffers in required ratio from supplied memory area
  while (nip->buff_area_size > rx_len || nip->buff_area_size > tx_len)
  {
    int n;
    for (n = 0; n < nip->rx_buffs; n += 1) {
      if (nip->buff_area_size < rx_len)
        break;
      p = (ADI_ETHER_BUFFER*)nip->buff_area;
      nip->buff_area += rx_len;
      nip->buff_area_size -= rx_len;
      p->pNext = rx_head;
      rx_head = p;
    }
    for (n = 0; n < nip->tx_buffs; n += 1) {
      if (nip->buff_area_size < tx_len)
        break;
      p = (ADI_ETHER_BUFFER*)nip->buff_area;
      nip->buff_area += tx_len;
      nip->buff_area_size -= tx_len;
      p->pNext = tx_head;
      tx_head = p;
    }
  }

  // initialise each buffer's ADI_ETHER_BUFFER descriptor
  p = rx_head;
  count = 0;
  while (p)
  {
    p->Data = (char*)p + sizeof(ADI_ETHER_BUFFER) + nip->buff_overhead;
    #if defined(__ADSPBF537__)
    if(p->Data >0) 
	    LWIP_ASSERT("Rx data buffers are not aligned properly",CHECK_ALIGNMENT((unsigned int)p->Data));
    #elif (defined(__ADSPBF533__) || defined(__ADSPBF561__))
    // first two bytes in the data buffer are used to store the length.
    if((p->Data >0) && (nip->buff_overhead > 0)) 
	    LWIP_ASSERT("Rx data buffers are not aligned properly",CHECK_ALIGNMENT((unsigned int)((char*)p->Data+ 2)));
    #endif /* __ADSPBF537__ */

    p->ElementCount = nip->rx_buff_datalen;
    p->ElementWidth = 1;
    p->CallbackParameter =p;
    p->ProcessedElementCount=0;
    p->ProcessedFlag =0;
    p->PayLoad = 0;
    p->x = netif;
   
    mangle_ptr = ((unsigned int*)&p->Reserved)+4;
    *((unsigned int*)mangle_ptr)= (unsigned int)((char*)p->Data + p->ElementCount - nip->buff_overhead);
    bip = (struct buffer_info*)(*(unsigned int*)mangle_ptr);
    bip->netif = netif;
    bip->max_buf_len = nip->rx_buff_datalen;
    count += 1;
    p = p->pNext;
  }
  nip->rx_buffs = count;
  
  p = tx_head;
  count = 0;
  while (p)
  {
    p->Data = (char*)p + sizeof(ADI_ETHER_BUFFER) + nip->buff_overhead;

    #if defined(__ADSPBF537__)
    if(p->Data >0) 
	    LWIP_ASSERT("Tx data buffers are not aligned properly",CHECK_ALIGNMENT((unsigned int)p->Data));
    #elif (defined(__ADSPBF533__) || defined(__ADSPBF561__))
    // first two bytes in the data buffer are used to store the length.
    if((p->Data >0) && (nip->buff_overhead > 0)) 
	    LWIP_ASSERT("Tx data buffers are not aligned properly",CHECK_ALIGNMENT((unsigned int)((char*)p->Data +2)));
    #endif /* __ADSPBF537__ */

    p->ElementCount = nip->tx_buff_datalen;
    p->ElementWidth = 1;
    p->CallbackParameter =p;
    p->x = netif;
    p->PayLoad = 0;

    mangle_ptr = ((unsigned int*)&p->Reserved)+4;
    *((unsigned int*)mangle_ptr)= (unsigned int)((char*)p->Data + p->ElementCount - nip->buff_overhead);

    bip = (struct buffer_info*)(*(unsigned int*)mangle_ptr);
	
    bip->netif = netif;
    bip->max_buf_len = nip->tx_buff_datalen;
    count += 1;
    p = p->pNext;
  }
  nip->tx_buffs = count;
  
  // set up this interface's TCPIP callback messages
  msg = &nip->txmsg;
  msg->type = TCPIP_MSG_CALLBACK;
  msg->flags = TCPIP_MSG_FLAG_STATIC;
  msg->msg.cb.function = process_xmtd_packets;
  msg->msg.cb.ctx = netif;
  msg = &nip->rxmsg;
  msg->type = TCPIP_MSG_CALLBACK;
  msg->flags = TCPIP_MSG_FLAG_STATIC;
  msg->msg.cb.function = process_rcvd_packets;
  msg->msg.cb.ctx = netif;
  
  // give all the rx buffers to the Ethernet device driver
  adi_dev_Read(nip->handle,ADI_DEV_1D,(ADI_DEV_BUFFER*)rx_head);

  // save the list of tx buffers until they are needed
  nip->x = tx_head;
}
Пример #9
0
static void process_rcvd_packets(void *arg_nif)
{
  struct netif* netif = (struct netif*)arg_nif;
  struct nifce_info* nip = (struct nifce_info*)netif->state;
  unsigned int *mangle_ptr;
  void *handle = nip->handle;
  int int_sts;

  ADI_ETHER_BUFFER* buffers_to_reuse;
  ADI_ETHER_BUFFER* buffers_to_process;
  ADI_ETHER_BUFFER* recycle_list = 0;
  ADI_ETHER_BUFFER* bp;
  ADI_ETHER_BUFFER* nbp;
  ADI_ETHER_BUFFER* lbp;

  // now check for received buffers
  int_sts = ker_disable_interrupts(ker_kPriorityLevelAll);
  buffers_to_process = nip->rcv_list;
  nip->rcv_list = NULL;
  nip->rxmsg_processed =0;
  ker_enable_interrupts(int_sts);	


  // create a pbuf for each received buffer and call eth_input to process it
  bp = buffers_to_process;
  while (bp != 0) 
  {
    struct hw_eth_hdr* ethhdr = (struct hw_eth_hdr*)((char*)bp->Data+2);

    u16_t length = bp->ProcessedElementCount - 6; // 2 + 4crc byte to store length
    struct pbuf* p;
    int unpack_arp = 0;

    nbp = bp->pNext;
    bp->pNext = 0;
    // (char*)bp->Data + 2 contrain the actual data.
    if (Trace_Function) Trace_Function('R',length,((unsigned char *)bp->Data+2));
    
    // see whether we need two extra u16_t fields for alignment
    if (length >= (sizeof(struct etharp_hdr) - 6) &&
            htons(ethhdr->type) == ETHTYPE_ARP) {
      length += 4; // need fields unused2 and unused3 in struct etharp_hdr
      unpack_arp = 1;
    }
    length += 2;// for field unused1 in struct eth_hdr
	
    p = pbuf_alloc(PBUF_RAW, length, PBUF_RAM);

    if (p != NULL) 
	{
      //u8_t* psrc = (u8_t*)bp->Data;
      u8_t* psrc = (u8_t*)bp->Data+2;
      u8_t* pdst = (u8_t*)p->payload;

      // set field unused1 to 0
      *(u16_t*)pdst = 0;
      pdst += 2;

      // copy in eth_hdr data
      memcpy(pdst, psrc, 14);
      pdst += 14;
      psrc += 14;

		if (unpack_arp) 
		{
			// copy etharp frame into pbuf up to field unused2
			memcpy(pdst, psrc, 14);
			pdst += 14;
			psrc += 14;
			// set field unused2 to 0
			*(u16_t*)pdst = 0;
			pdst += 2;
			// copy more of frame up to field unused3
			memcpy(pdst, psrc, 10);
			pdst += 10;
			psrc += 10;
			// set field unused3 to 0
			*(u16_t*)pdst = 0;
			pdst += 2;
			// copy remainder of frame
			memcpy(pdst, psrc, 4);
		} else 
		{
			  // just copy the rest of the frame into the pbuf in one go
		  	 memcpy(pdst, psrc, length - 16);
		}
#ifdef LINK_STATS
      lwip_stats.link.recv++;
#endif

      mangle_ptr = ((unsigned int*)&bp->Reserved)+4; // TODO: get-rid of Reserved.
      eth_input(p, ((struct buffer_info*)(*((unsigned int*)mangle_ptr)))->netif);
    } // p!=NULL 
	else 
	{
#ifdef LINK_STATS
      lwip_stats.link.memerr++;  // had to drop frame - no memory for pbuf
#endif

    }
	mangle_ptr = ((unsigned int*)&bp->Reserved)+4;
    bp->ElementCount = ((struct buffer_info*)(*((unsigned int*)mangle_ptr)))->max_buf_len;
    bp->CallbackParameter = bp;
    bp->PayLoad =0;
    bp->StatusWord =0;
    bp->ProcessedElementCount=0;
    bp->ProcessedFlag =0;
    bp->pNext = recycle_list;
    recycle_list = bp;

    bp = nbp;
  } // while

  // return the buffers to the driver

  if (recycle_list != 0)
	  adi_dev_Read(nip->handle,ADI_DEV_1D,(ADI_DEV_BUFFER*)recycle_list);

}
Пример #10
0
static u32 adi_pdd_Read(
    ADI_DEV_PDD_HANDLE PDDHandle,   /* PDD handle */
    ADI_DEV_BUFFER_TYPE BufferType, /* buffer type */
    ADI_DEV_BUFFER *pBuffer         /* pointer to buffer */
)
{
    u32                         Result;

    /* Expose the Device Definition structure */
    ADI_USB_DEF                 *pDevice = (ADI_USB_DEF *)PDDHandle;

    /* Expose the FSS super buffer structure */
    ADI_FSS_SUPER_BUFFER        *pSuperBuffer = (ADI_FSS_SUPER_BUFFER *)pBuffer;

    /* Assign callback function and handle to Super Buffer */
    pSuperBuffer->PIDCallbackFunction = CallbackFromFSS;
    pSuperBuffer->PIDCallbackHandle = (void*)pDevice;

#if defined(_BF527_SDRAM_ISSUE_WORKAROUND)
    /* tranfser 'gEndPointMaxPacketSize' bytes at at time & copy to request buffer */
    ADI_DEV_1D_BUFFER  TempBuffer, *pClientBuffer;
    u32                 BytesRemaining = pBuffer->OneD.ElementCount*pBuffer->OneD.ElementWidth;
    u32                 *pClientData   = (u32*)pBuffer->OneD.Data;
    u32                 *pTempData;
    u32                 i;
    u32                 SectorNumber   = pSuperBuffer->LBARequest.StartSector;
    u32                 BufferSize;
    u32                 SectorIncrement;

    if (BytesRemaining< TEMP_BUF_SIZE) {
        BufferSize = BytesRemaining;
    } else {
        BufferSize = TEMP_BUF_SIZE;
    }

    SectorIncrement = BufferSize/512;

    /* change LBA request to 1 sector */
    pSuperBuffer->LBARequest.SectorCount = SectorIncrement;

    /* get max end point buffer size from MSH class driver */
    //adi_dev_Control( pDevice->ClassDriverHandle, ADI_USB_MSD_CMD_GET_MAX_EP_PACKET_SIZE, (void*)&TempBuffer.ElementCount );

    TempBuffer.Data = (void*)&TempBufferData[0];
    TempBuffer.ElementCount = BufferSize;
    TempBuffer.ElementWidth = sizeof(u8);
    TempBuffer.ProcessedElementCount = 0;
    TempBuffer.ProcessedFlag = FALSE;
    TempBuffer.CallbackParameter = &TempBuffer;
    TempBuffer.pNext = NULL;

    pClientBuffer = &pSuperBuffer->Buffer;

    while (pClientBuffer)
    {
        while (BytesRemaining)
        {
            pDevice->ClassCommandComplete = FALSE;
            /* Pass LBA request to the Class Driver */
            SendLbaRequest(pDevice,&pSuperBuffer->LBARequest);
            /* Queue the buffer */
            Result = adi_dev_Read( pDevice->ClassDriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER*)&TempBuffer );
            if (Result!=ADI_DEV_RESULT_SUCCESS) {
                return Result;
            }

            /* and wait for completion */
            WaitOnCommandCompletion(pDevice);

            pTempData = (u32*)&TempBufferData[0];

            /* If a Memory DMA stream has been registered with the driver then it is used for the
             * transfer between the L1 temporary buffer and the client buffer
            */
            if (pDevice->MemDMAStreamHandle) {
                adi_dma_MemoryCopy(
                                    pDevice->MemDMAStreamHandle,            /* Stream Handle      */
                                    pClientData,                            /* Destination buffer */
                                    pTempData,                              /* Source buffer      */
                                    sizeof(u32),                            /* Element Width      */
                                    (TempBuffer.ElementCount)/sizeof(u32),  /* Number of elements */
                                    MemDmaCallback                          /* Callback function  */
                                    );

                /* pend on completion */
                adi_sem_Pend(MemDmaSemaphoreHandle,ADI_SEM_TIMEOUT_FOREVER);
                pClientData += (TempBuffer.ElementCount)/sizeof(u32);
            }
            /* Otherwise a core copy is used */
            else {
                for(i=0;i<(TempBuffer.ElementCount)/sizeof(u32);i++,pClientData++,pTempData++)
                {
                    *pClientData = *pTempData;
                }
            }

            BytesRemaining -= TempBuffer.ElementCount;
            pSuperBuffer->LBARequest.StartSector += SectorIncrement;
        }

        pClientBuffer = pClientBuffer->pNext;
    }

    (pDevice->DMCallback) ( pDevice->DeviceHandle, ADI_DEV_EVENT_BUFFER_PROCESSED, (void *)pBuffer );
    (pDevice->DMCallback) ( pDevice->DeviceHandle, ADI_PID_EVENT_DEVICE_INTERRUPT, (void *)pBuffer);


#else
#if defined(_USE_BACKG_XFER)
    /* save aside the next buffer in the chain */
    pNextBufferInChain = (ADI_FSS_SUPER_BUFFER *)pBuffer->OneD.pNext;

    /* and clear it so that the USB driver only deals with a single buffer */
    pBuffer->OneD.pNext = NULL;
#endif

#if defined(_USE_BACKG_XFER)
    /* Pass LBA request to the Class Driver */
    SendLbaRequest(pDevice,&pSuperBuffer->LBARequest);
#endif

    /* Pass on the request to the Class Driver */
    Result = adi_dev_Read( pDevice->ClassDriverHandle, BufferType, pBuffer );
#endif

    return(Result);
}
Пример #11
0
/*********************************************************************

    Function:       CallbackFromFSS

    Description:    This is the callback to be taken from the Class
                    Driver.
*********************************************************************/
static void ClassDriverCallback(void *pHandle, u32 Event, void *pArg)
{
    ADI_USB_DEF *pDevice = (ADI_USB_DEF *)pHandle;
    void        *pExitCriticalArg;
    u32         Result;

    switch (Event)
    {
        /* CASE (USB DEVICE INSERTED) */
        case ADI_USB_EVENT_CONNECT:
            /* Callback FSS with ADI_FSS_EVENT_MEDIA_DETECTED event, which may pass the event on to
             * the application which can take action to Poll for Media.
            */
#if 0            
            if (FSSDirectCallbackFunction) {
                (FSSDirectCallbackFunction)( &pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_DETECTED, 0 );
            } else {
                (pDevice->DMCallback) ( pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_DETECTED, 0 );
            }
#endif            
            if (MediaDetectionCallbackFunction) {
                (MediaDetectionCallbackFunction)( &pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_DETECTED, 0 );
            }
            break;

        /* CASE (USB DEVICE REMOVED) */
        case ADI_USB_EVENT_DISCONNECT:
            /* simply flag as not present. Next ADI_PID_CMD_POLL_MEDIA_CHANGE command will
             * result in the ADI_FSS_EVENT_MEDIA_REMOVED event being sent to FSS.
            */
            if (pDevice->MediaPresent)
            {
                pDevice->MediaPresent = FALSE;
            }
            if (MediaDetectionCallbackFunction) {
                (MediaDetectionCallbackFunction)( &pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_REMOVED, 0 );
            }
            break;

        /* CASE (USB DATA TRANSFER COMPLETE) */
        case ADI_DEV_EVENT_BUFFER_PROCESSED:
           /* pass on event to FSS via DM callback */
#if !defined(_BF527_SDRAM_ISSUE_WORKAROUND)
           (pDevice->DMCallback)( pDevice->DeviceHandle, Event, pArg);
#endif

           /* If there is another buffer in the chain, send the next LBA request and
            * queue the next buffer with the class driver
           */
#if defined(_USE_BACKG_XFER)
           if (pNextBufferInChain)
           {
               ADI_FSS_SUPER_BUFFER *pSuperBuffer = pNextBufferInChain;

               /* The next buffer may not have an LBA Request associated with it, as
                * it may have been combimed with the previous buffer. In which case
                * we do not need to send the LBA request
               */
               if (pSuperBuffer->LBARequest.SectorCount)
               {
                   SendLbaRequest(pDevice, &pSuperBuffer->LBARequest);
               }
               pNextBufferInChain = (ADI_FSS_SUPER_BUFFER *)pSuperBuffer->Buffer.pNext;
               pSuperBuffer->Buffer.pNext = NULL;

               /* Queue the data buffer with the class driver */
               if (pSuperBuffer->LBARequest.ReadFlag)
               {
                    adi_dev_Read( pDevice->ClassDriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)pSuperBuffer);
               }
               else
               {
                    adi_dev_Write( pDevice->ClassDriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)pSuperBuffer );
               }
           }
           else
#endif
           {
               /* At the end of the chain we issue the Device Interrupt event to signal
                * total completion
               */
#if defined(_BF527_SDRAM_ISSUE_WORKAROUND)
                pExitCriticalArg = adi_int_EnterCriticalRegion( pDevice->pEnterCriticalArg );
                pDevice->ClassCommandComplete = TRUE;
                adi_int_ExitCriticalRegion(pExitCriticalArg);
#else
               (pDevice->DMCallback)( pDevice->DeviceHandle, ADI_PID_EVENT_DEVICE_INTERRUPT, pArg);
#endif
           }
            break;

        case ADI_USB_MSD_EVENT_SCSI_CMD_COMPLETE:
            /* post the semaphore upon which the DevicePollMedia function is pending */
            pExitCriticalArg = adi_int_EnterCriticalRegion( pDevice->pEnterCriticalArg );
            pDevice->ClassCommandComplete = TRUE;
            adi_int_ExitCriticalRegion(pExitCriticalArg);
        break;

        case ADI_USB_MSD_EVENT_SCSI_CMD_ERROR:
            pExitCriticalArg = adi_int_EnterCriticalRegion( pDevice->pEnterCriticalArg );
            pDevice->SCSICommandError = TRUE;
            adi_int_ExitCriticalRegion(pExitCriticalArg);
        break;
        
        case ADI_FSS_EVENT_MEDIA_ERROR:
        {
            if (FSSDirectCallbackFunction)
            {
                (FSSDirectCallbackFunction)( &pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_REMOVED, 0 );
            } else 
            {
                (pDevice->DMCallback) ( pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_REMOVED, 0 );
            }
        }
        break;
    }
}