⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nbuf.c

📁 [拉普兰德]TSL1401线性CCD模块资料包
💻 C
字号:
/* Buffer Descriptors -- must be aligned on a 4-byte boundary but a 
 * 16-byte boundary is recommended. To avoid playing games with the 
 * various compilers and their different extension to ANSI C, these 
 * buffers are aligned by allocating an extra line of data and 
 * adjusting the pointers in nbuf_init().
 */

#include "common.h"
#include "nbuf.h"

/*FSL: to avoid overlapping, buffers must be declared at the beggining of file*/
/*then pointers can access them correctly*/

/* Data Buffers -- must be aligned on a 16-byte boundary. To avoid 
 * playing games with the various compilers and their different 
 * extension to ANSI C, these buffers are aligned by allocating an 
 * extra line of data and adjusting the pointers in nbuf_init().
 */
static uint8_t unaligned_txbd[(sizeof(NBUF) * NUM_TXBDS) + 16];
static uint8_t unaligned_rxbd[(sizeof(NBUF) * NUM_RXBDS) + 16];
#ifdef USE_DEDICATED_TX_BUFFERS
static uint8_t unaligned_txbuffer[(TX_BUFFER_SIZE * NUM_TXBDS) + 16];
#endif
static uint8_t unaligned_rxbuffer[(RX_BUFFER_SIZE * NUM_RXBDS) + 16];

/* Pointers to alligned buffer descriptors */
static NBUF *TxNBUF;
static NBUF *RxNBUF;

/* Pointers to alligned Tx/Rx data buffers */
#ifdef USE_DEDICATED_TX_BUFFERS
static uint8_t *TxBuffer;
#endif
static uint8_t *RxBuffer;

/* Next BD indicators for static BD queue */ 
static int next_txbd;
static int next_rxbd;

/********************************************************************/
void 
nbuf_alloc(int ch)
{
	int i;
	//uint32_t *temp;

        next_txbd = 0;
        next_rxbd = 0;

	TxNBUF = (NBUF *)(((uint32_t)(unaligned_txbd)) & 0xFFFFFFF0);
	RxNBUF = (NBUF *)(((uint32_t)(unaligned_rxbd)) & 0xFFFFFFF0);

	RxBuffer = (uint8_t *)(((uint32_t)(unaligned_rxbuffer)) & 0xFFFFFFF0);
#ifdef USE_DEDICATED_TX_BUFFERS
	TxBuffer = (uint8_t *)(((uint32_t)(unaligned_txbuffer)) & 0xFFFFFFF0);
#endif
	// Initialize transmit descriptor ring
	for (i = 0; i < NUM_TXBDS; i++)
	{
		TxNBUF[i].status = 0x0000;
		TxNBUF[i].length = 0;		
	        #ifdef USE_DEDICATED_TX_BUFFERS
	           #ifdef NBUF_LITTLE_ENDIAN 
	           TxNBUF[i].data = (uint8_t *)__REV((uint32_t)&TxBuffer[i * TX_BUFFER_SIZE]);
                   #else
                   TxNBUF[i].data = (uint8_t *)(uint32_t)&TxBuffer[i * TX_BUFFER_SIZE];
                   #endif
                #endif
        
                #ifdef ENHANCED_BD
                   TxNBUF[i].ebd_status = TX_BD_IINS | TX_BD_PINS;
                #endif
	}

	// Initialize receive descriptor ring
	for (i = 0; i < NUM_RXBDS; i++)
	{
		RxNBUF[i].status = RX_BD_E;
		RxNBUF[i].length = 0;
                #ifdef NBUF_LITTLE_ENDIAN
		RxNBUF[i].data = (uint8_t *)__REV((uint32_t)&RxBuffer[i * RX_BUFFER_SIZE]);
                #else
                RxNBUF[i].data = (uint8_t *)(uint32_t)&RxBuffer[i * RX_BUFFER_SIZE];
                #endif

                #ifdef ENHANCED_BD
	        RxNBUF[i].bdu = 0x00000000;
	        RxNBUF[i].ebd_status = RX_BD_INT;
                #endif               
	}
        
	// Set the Wrap bit on the last one in the ring
	RxNBUF[NUM_RXBDS - 1].status |= RX_BD_W;
	TxNBUF[NUM_TXBDS - 1].status |= TX_BD_W;
}
/********************************************************************/
void 
nbuf_flush(int ch)
{
	int i;

	next_txbd = 0;
	next_rxbd = 0;
	
	// Reset enet hardware bd pointers also ??

	// Reset receive descriptor ring
	for (i = 0; i < NUM_RXBDS; i++)
	{
		RxNBUF[i].status = RX_BD_E;
		RxNBUF[i].length = 0;
	        #ifdef NBUF_LITTLE_ENDIAN	
		RxNBUF[i].data = (uint8_t *)__REV((uint32_t)&RxBuffer[i * RX_BUFFER_SIZE]);
	        #else
	        RxNBUF[i].data = (uint8_t *)(uint32_t)&RxBuffer[i * RX_BUFFER_SIZE];
	        #endif	
	}

	// Reset transmit descriptor ring
	for (i = 0; i < NUM_TXBDS; i++)
	{
		TxNBUF[i].status = 0x0000;
		TxNBUF[i].length = 0;
	}

	// Set the Wrap bit on the last one in the ring
	RxNBUF[NUM_RXBDS - 1].status |= RX_BD_W;
	TxNBUF[NUM_TXBDS - 1].status |= TX_BD_W;
}
/********************************************************************/
void 
nbuf_init(int ch)
{
	// Set Receive Buffer Size
	ENET_MRBR/*(ch)*/ = (uint16_t)RX_BUFFER_SIZE;  
  
 	// Point to the start of the Tx buffer descriptor queue
	ENET_TDSR/*(ch)*/ = (uint32_t)TxNBUF;
	// Point to the start of the circular Rx buffer descriptor queue
	ENET_RDSR/*(ch)*/ = (uint32_t)RxNBUF;
}
/********************************************************************/
void 
nbuf_start_rx(int ch)
{
        // Indicate Empty buffers have been produced
	ENET_RDAR/*(ch)*/ = ENET_RDAR_RDAR_MASK;

        while( !ENET_RDAR )
        {
          //If RDAR cannot be test,  
          //printf("Error with internal ENET DMA engine\n");
        }
}
/********************************************************************/
void 
enet_get_received_packet(int ch, NBUF * rx_packet)
{
	int last_buffer;
	uint16_t status;
	int index_rxbd;

	last_buffer = 0;
	rx_packet->length = 0;
	
	index_rxbd = next_rxbd;
    
	if(RxNBUF[index_rxbd].status & RX_BD_E)
	{
		printf("Under processing. SHouldnt be here\n");
		return;	
	}
        #ifdef NBUF_LITTLE_ENDIAN
        rx_packet->data = (uint8_t *)__REV((uint32_t)RxNBUF[index_rxbd].data);
        #else
        rx_packet->data = (uint8_t *)(uint32_t)RxNBUF[index_rxbd].data;
        #endif
	// Update next_rxbd pointer and mark buffers as empty again
	while(!last_buffer)
	{
		status = RxNBUF[index_rxbd].status;
	        #ifdef NBUF_LITTLE_ENDIAN	
		rx_packet->length = __REVSH(RxNBUF[index_rxbd].length);
                #else
                rx_packet->length = RxNBUF[index_rxbd].length;
                #endif
                #ifdef ENHANCED_BD
		rx_packet->ebd_status = RxNBUF[index_rxbd].ebd_status;
	            #ifdef NBUF_LITTLE_ENDIAN	
		    rx_packet->timestamp = __REV(RxNBUF[index_rxbd].timestamp);
		    rx_packet->length_proto_type = __REVSH(RxNBUF[index_rxbd].length_proto_type);
		    rx_packet->payload_checksum = __REVSH(RxNBUF[index_rxbd].payload_checksum);
                    #else
		    rx_packet->timestamp = RxNBUF[index_rxbd].timestamp;
		    rx_packet->length_proto_type = RxNBUF[index_rxbd].length_proto_type;
		    rx_packet->payload_checksum = RxNBUF[index_rxbd].payload_checksum;
                    #endif
                #endif

		last_buffer = (status & RX_BD_L);
		if(status & RX_BD_W)
		{
			RxNBUF[index_rxbd].status = (RX_BD_W | RX_BD_E);
			index_rxbd = 0;
		}
		else
		{
			RxNBUF[index_rxbd].status = RX_BD_E;
			index_rxbd++;
		}
	}
	
	// Update the global rxbd index
	next_rxbd = index_rxbd;
	
	// Put the last BD status in rx_packet->status as MISS flags and more 
	// are updated in last BD
	rx_packet->status = status;
}
/********************************************************************/
void enet_fill_txbds(int ch, NBUF * tx_packet)
{
	int num_txbds, i;
	int index_txbd;

	num_txbds = (tx_packet->length/TX_BUFFER_SIZE);
	
	index_txbd = next_txbd;
	
	if((num_txbds * TX_BUFFER_SIZE) < tx_packet->length)
	{
		num_txbds = num_txbds + 1;
	}
    
	// Fill Descriptors
	for (i = 0; i < num_txbds; i++)
	{
		
		TxNBUF[index_txbd].status = TX_BD_TC | TX_BD_R;
                #ifdef ENHANCED_BD
		TxNBUF[index_txbd].bdu = 0x00000000;
		TxNBUF[index_txbd].ebd_status = TX_BD_INT | TX_BD_TS;// | TX_BD_IINS | TX_BD_PINS;
                #endif

		if(i == num_txbds - 1)
		{
		    #ifdef NBUF_LITTLE_ENDIAN 
		    TxNBUF[index_txbd].length = __REVSH((tx_packet->length - (i*TX_BUFFER_SIZE)));
                    #else
                    TxNBUF[index_txbd].length = (tx_packet->length - (i*TX_BUFFER_SIZE));
                    #endif
		    // Set the Last bit on the last BD
		    TxNBUF[index_txbd].status |= TX_BD_L;		 
		}
		else
		{
		    #ifdef NBUF_LITTLE_ENDIAN 
		    TxNBUF[index_txbd].length = __REVSH(TX_BUFFER_SIZE);
		    #else
		    TxNBUF[index_txbd].length = TX_BUFFER_SIZE;
		    #endif
		}
		
		#ifdef USE_DEDICATED_TX_BUFFERS
		  #ifdef NBUF_LITTLE_ENDIAN
		  //Copy data to Tx buffers
                   memcpy((void *)__REV((uint32_t)TxNBUF[index_txbd].data), (void *)(((uint32_t)(tx_packet->data)) + (i*TX_BUFFER_SIZE)),
                          __REVSH(TxNBUF[index_txbd].length));  
                  #else
		  // Copy data to Tx buffers
                  memcpy((void *)(uint32_t)TxNBUF[index_txbd].data, (void *)(((uint32_t)(tx_packet->data)) + (i*TX_BUFFER_SIZE)),
                          TxNBUF[index_txbd].length);         
                  #endif
                #else
                  // Just update data pointer as data is aready there
                  #ifdef NBUF_LITTLE_ENDIAN 
                  TxNBUF[index_txbd].data = (uint8_t *)__REV((((uint32_t)(tx_packet->data)) + (i*TX_BUFFER_SIZE)));
                  #else
                  TxNBUF[index_txbd].data = (uint8_t *)(((uint32_t)(tx_packet->data)) + (i*TX_BUFFER_SIZE));
                  #endif 
                #endif

		// Wrap if this was last TxBD
		if(++index_txbd == NUM_TXBDS)
		{
			TxNBUF[NUM_TXBDS - 1].status |= TX_BD_W;
			index_txbd = 0;
		}
	}
	
	// Update the global txbd index
	next_txbd = index_txbd;
}

void 
enet_transmit_packet(int ch, NBUF * tx_packet)
{
	enet_fill_txbds(ch,tx_packet);
	
	// Indicate that Descriptors are ready to transmit 
	ENET_TDAR/*(ch)*/ = ENET_TDAR_TDAR_MASK;
}
/********************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -