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

📄 pxa-gspi.c

📁 自制PDA系列之SPI接口无线局域网卡驱动(处理器S3C2410(PXA270的版本本人还没改好
💻 C
📖 第 1 页 / 共 4 页
字号:

	///crlo: If the data length is NOT multiple of DWORD, add more
	///	crlo: ref: SPU specification chap4
	{
		if (((nbyte %4) != 0) && ((reg ==0x0c)||(reg ==0x18)||(reg ==0x24) ))
		{
			///crlo: Because we are using 16-bit data accessing, if (nyte%4)!=0, it must be 2
			///		=> add one more WORD
			//pHC->pSSPRegs->base.ssdr = 0;

                   temp=0;
                  while((pHC->pSSPRegs->SPSTA0 & 0x1)==0);	// wait while busy

	          pHC->pSSPRegs->SPTDAT0 = (UCHAR)(temp >> 8);	                // write 1st Byte
              //    RETAILMSG(1,(L"ssp_write_data_direct(): Reg 1st Byte=(0x%x)\n", (UCHAR)(temp >> 8)));
               	  while((pHC->pSSPRegs->SPSTA0 & 0x1)==0);	// wait while busy

	          pHC->pSSPRegs->SPTDAT0 = (UCHAR)(temp & 0x00ff);	                // write 2nd Byte	
              //    RETAILMSG(1,(L"ssp_write_data_direct(): Reg 1st Byte=(0x%x)\n", (UCHAR)(temp & 0x00ff)));
	          while((pHC->pSSPRegs->SPSTA0 & 0x1)==0);	// wait while busy


			
		
			//udelay( 10);
			GSPIMSG(1, (TEXT("Add one more WORD to fit 32-bit boundary\n"), accnbyte));
		}
	}
	
 	pHC->pGPIORegs->GPGDAT |= (0x1 << 2);        //Set _SS signal to high (Slave Select)
                    
    

	
	LeaveCriticalSection(&pHC->SSPCrit);
funcLeave:
	EXITFUNC(result);
	
	return result;
}

static GSPI_STATUS setup_read_dma(PSSP_HARDWARE_CONTEXT pHC, int n)
{
	GSPI_STATUS		result = GSPI_SUCCESS;
	DWORD			dmaresult;
    //DWORD			TC;


	MYDMAPARAM		*pwtDmaParam = &pHC->DMAParam[RWDMA_PARAM];

// DMA mode, CLK enable, master mode, active high clock, format A, Tx Auto Garbage Data mode
pHC->pIntRegs->INTMSK&= ~(0x1<<18);//DMA1 service available
pHC->pSSPRegs->SPCON0 = (0x2<<5)|(1<<4)|(1<<3)|(0<<2)|(0<<1)|(1<<0);

pHC->pDMARegs->DISRC1= (unsigned)0x59000014;//SPI0 SPRDAT0 register(Physical Address)
pHC->pDMARegs->DISRCC1=(1<<1) | (1); //APB(SPI), fixed
//pHC->pDMARegs->DIDST1=	(unsigned) (pHC->iodata);//Virtual address
pHC->pDMARegs->DIDST1=	(unsigned) (pHC->phys_addr);//Phy address
pHC->pDMARegs->DIDSTC1=(0<<1) | (0);//AHB(Memory), inc
//Handshake Mode(31) , sync PCLK(30), TC intr(29), single TX(28), single service(27), 
//request source SPI(26..24), H/W request(23), off-reload(22), data size:byte(21..20), transfer count
       
pHC->pDMARegs->DCON1=(1<<31) |(0<<30)|(1<<29)|(0<<28)|(0<<27)|(3<<24)|(1<<23)|(1<<22)|(0<<20)|(n);


#if (USE_DMAIRQ == 1)	
	ResetEvent(pwtDmaParam->dmaWaitObj);
#endif ///USE_DMAIRQ

pHC->pDMARegs->DMASKTRIG1=(0<<2)|(1<<1)|(0);//run, channel on, no s/w trigger

#if (USE_DMAIRQ == 1)
	dmaresult = WaitForSingleObject(pwtDmaParam->dmaWaitObj, (MAX_WAITus/1000));
	if (dmaresult == WAIT_TIMEOUT) {
		GSPIMSG(1, (TEXT("WaitForSingleObject timeout (%d)\n"), n));
		result = GSPI_TIMEOUT;
		goto funcFinal;
	}
pHC->pDMARegs->DMASKTRIG1=(0<<2)|(0<<1)|(0);//run, channel off, no s/w trigger
//pHC->pSSPRegs->SPCON0 = (0<<5)|(1<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0);		
#endif
	

funcFinal:
	return result;
}

static GSPI_STATUS ssp_read_data_direct(DWORD hDC, WORD* data, WORD reg, WORD nword, WORD dummy_clk)
{
	GSPI_STATUS		result = GSPI_SUCCESS;	
	PSSP_HARDWARE_CONTEXT	pHC;
	WORD	nbyte = nword * 2;
	//WORD temp,tt1,tt2;
	WORD temp;
//	int		i,ii;
    int		i;
	BYTE temp1;
	PWORD	dat = (PWORD)data;
	PBYTE p;
	#if (USE_DMA == 1)
	int		accnbyte;				///Accumulated length (0 - nbyte)
	int		fragnbyte;				///length of each fragment
	BOOLEAN	 isfrag = FALSE;
	#endif /// (USE_DMA == 1)
//GSPIMSG(1, (TEXT("nword=(%d)\n"), nword));
//GSPIMSG(1, (TEXT("nbyte=(%d)\n"), nbyte));
	ENTERFUNC();
	if (hDC == 0) {
		result = GSPI_INVALIDARGS;
		goto funcLeave;
	}
	pHC = (PSSP_HARDWARE_CONTEXT)hDC;

	EnterCriticalSection(&pHC->SSPCrit);

pHC->pGPIORegs->GPGDAT &= ~(0x1 << 2);       //Set _SS signal to low (Slave Select)		

	
#if (USE_DMA == 1)
	///DMA mode
	{
	///Write the register address

	
	WORD *iodatPt = (WORD*)pHC->iodata;
//	for(i=0;i<(1+dummy_clk);i++)
//		  *(iodatPt+i)=0;
	//WORD *iodatPt = (WORD*)pHC->iorw;
	*iodatPt = reg;

	
temp1=*(pHC->iodata);	
*(pHC->iodata)=*(pHC->iodata+1);
*(pHC->iodata+1)=temp1;	
	

      result = setup_write_dma(pHC, (1+dummy_clk)*2);
	//result = setup_read_dma(pHC, (1+dummy_clk)*2);
	if (result != GSPI_SUCCESS) {
		GSPIMSG(1, (TEXT("Fail to push reg+dummy_clk[%d]...\n"), dummy_clk));
	}
	}

	///==============================================
	accnbyte = 0;
	while (1) {
		fragnbyte = nbyte - accnbyte;
		if (fragnbyte> PXA_SSP_IODATA_SIZE) {
			fragnbyte = PXA_SSP_IODATA_SIZE;	
			isfrag = TRUE;
		}

		result = setup_read_dma(pHC, fragnbyte);
		if (result != GSPI_SUCCESS) {
			GSPIMSG(1, (TEXT("%s, Read data failed...\n"), TEXT(__FUNCTION__)));
			break;
		}
		
		memcpy((PBYTE)dat, pHC->iodata, fragnbyte);
		//memcpy(data, pHC->iodata, fragnbyte);
		//0524
		
		//for(i=0;i<fragnbyte;i++)
              //      GSPIMSG(1, (TEXT("%02X "), *(pHC->iodata+i)));  
		
		accnbyte += fragnbyte;
		dat += (fragnbyte/2);			///type of data is WORD
		if (accnbyte == nbyte) {
			if (isfrag == TRUE) {
				GSPIMSG(1, (TEXT("Cont. reading data. (now, exp)=(%d, %d), complete!\n"), accnbyte, nbyte));
			}
			break;
		} else if (accnbyte > nbyte){
			GSPIMSG(1, (TEXT("Invalid Rd Length, (exp, acc)=(%d, %d)\n"), nbyte, accnbyte));
		} else {
			if (isfrag == TRUE) {
				GSPIMSG(1, (TEXT("Cont. reading data. (now, exp)=(%d, %d)\n"), accnbyte, nbyte));
			}
		}
	}


// poll mode, CLK enable, master mode, active high clock, format A, normal mode
pHC->pSSPRegs->SPCON0 = (0<<5)|(1<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0);
pHC->pSSPRegs->SPPIN0= ((0<<2) |(1<<1) |(0<<0));

//read last byte
        //   while((pHC->pSSPRegs->SPSTA0 & 0x1)==0);	// wait while busy
        //   pHC->pSSPRegs->SPTDAT0 = (UCHAR)(0xff);	                
           while((pHC->pSSPRegs->SPSTA0 & 0x1)==0);	// wait while busy
           temp=pHC->pSSPRegs->SPRDAT0;
//           temp=temp<<8;

//GSPIMSG(1, (TEXT("Last Byte=%X\n"),temp)); 
//GSPIMSG(1, (TEXT("Before Swap....data0=%X data1=%X data2=%X data3=%X\r\n"),*(data),*(data+1),*(data+2),*(data+3))); 
//GSPIMSG(1, (TEXT("Before Swap....\r\n")));
//for(i=0;i<nword;i++)
//  GSPIMSG(1, (TEXT("%04X "), *(data+i))); 

p = (PBYTE)data;
//p = data;
/*
for(i=0;i<nword*2-1;i++)
{
	//need to check further
       // *(data+i)=(*(data+i) << 8)  | (*(data+i+1) >> 8);  
        *(p+i)=*(p+i+1);  
}
*(p+nword*2-1)=temp;
*/


for(i=0;i<nword-1;i++)
{
	//need to check further
       // *(data+i)=(*(data+i) << 8)  | (*(data+i+1) >> 8);  
        *(p+i*2)=*(p+(i+1)*2);
   
}
*(p+(nword-1)*2)=temp;
//*(p+(nword-1))=temp;

//GSPIMSG(1, (TEXT("After Swap....data0=%X data1=%X data2=%X data3=%X\r\n"),*(data),*(data+1),*(data+2),*(data+3))); 
//GSPIMSG(1, (TEXT("After Swap....\r\n")));
//for(i=0;i<nword;i++)
//GSPIMSG(1, (TEXT("%04X "), *(data+i))); 
/*
for(i=0;i<nword-1;i++)
{
	//need to check further
       // *(data+i)=(*(data+i) << 8)  | (*(data+i+1) >> 8);  
        *(data+i)=(*(data+i) << 8)  | (*(data+i+1) << 8);  
}

*(data+nword-1)=(*(data+nword-1) & 0xff00)  | temp;
GSPIMSG(1, (TEXT("data0=%X data1=%X\n"),*(data),*(data+1))); 
*/		   
	

#else
	///CPU mode
	{

	pHC->pSSPRegs->SPTDAT0 = (UCHAR)(reg >> 8);	                // write 1st Byte
        while((pHC->pSSPRegs->SPSTA0 & 0x1)==0);	// wait while busy
        pHC->pSSPRegs->SPTDAT0 = (UCHAR)(reg & 0x00ff);	                // write 2nd Byte	
        while((pHC->pSSPRegs->SPSTA0 & 0x1)==0);	// wait while busy
	
	for (i=0 ; i<dummy_clk*2 ; i++)
	//for (i=0;i<10;i++)
        {
           putcToSoc(pHC,0x00);

        } 

	
       }
       
	{
	//PWORD	dat = (PWORD)data;
	WORD t1;

	///================================
	/// Write the dummy_write & fetch the data
	///GSPIMSG(1, (TEXT("Reading datas(%d)WORD\n"), nword));
	//for (i=0 ; i<nword+10 ; i++) {
	
            for (i=0;i<nword;i++) 
        {	

//Begin to read data
           while((pHC->pSSPRegs->SPSTA0 & 0x1)==0);	// wait while busy
           pHC->pSSPRegs->SPTDAT0 = (UCHAR)(0xff);	                
           while((pHC->pSSPRegs->SPSTA0 & 0x1)==0);	// wait while busy
           temp=pHC->pSSPRegs->SPRDAT0;

          // RETAILMSG(1,(L"temp=(0x%X)  ", temp));

            udelay(10);

           temp=temp<<8;
           pHC->pSSPRegs->SPTDAT0 = (UCHAR)(0xff);	                
           while((pHC->pSSPRegs->SPSTA0 & 0x1)==0);	// wait while busy
           t1=pHC->pSSPRegs->SPRDAT0;
           temp=temp | t1;

           // RETAILMSG(1,(L"t1=(0x%X)  ", t1));
            *dat=temp;
          //  RETAILMSG(1,(L"%02d READ Value=(0x%x)\r\n", i,*dat));
               
          dat ++;
			
	}
	///GSPIMSG(1, (TEXT("Reading data done!\n")));
	}
#endif
 
   	pHC->pGPIORegs->GPGDAT |= (0x1 << 2);        //Set _SS signal to high (Slave Select)
        goto funcFinal;


funcFinal:
	LeaveCriticalSection(&pHC->SSPCrit);
funcLeave:
	EXITFUNC(result);
	
	return result;
}


///
/// ssp_read_register: Read the register from SSP interface
/// Input: 
///		hDC - the context returned from SSP_Init
///		regaddr - register addreess
///	Output:
///		regdatPt - returned register value
///	Return: 
///		0 - success
///		-1 - failure
GSPI_STATUS ssp_read_register(DWORD hDC, WORD* regdatPt, WORD regaddr)
{
	GSPI_STATUS	result=0;
	//BYTE *p,tb;
	int			i;

	for (i=0 ; i<GSPI_MAX_REG_RETRY ; i++) {
		result = ssp_read_data_direct(hDC, regdatPt, regaddr, 1, g_spi_dummy_clk_reg);
		if (result == GSPI_SUCCESS) {
			break;
		}
	}
	if (i == GSPI_MAX_REG_RETRY) {
		GSPIMSG(1, (L"%s, Read register(%xh) timeout \n", TEXT(__FUNCTION__), regaddr));
		result = GSPI_TIMEOUT;
	}
/*	
       p=(PBYTE)regdatPt;
	tb=*(p+1);
	*(p+1)=*p;
	*p=tb;
*/	
	return result;
}

///
/// ssp_write_register: Write the register from SSP interface
/// Input: 
///		hDC - the context returned from SSP_Init
///		regaddr - register addreess
///		regdat - register value to write
///	Output:
///		None
///	Return:
///		0 - success
///		-1 - failure

//              regval = 0x06;
//		ssp_write_register((DWORD)pHC, 0x70, &regval);
GSPI_STATUS ssp_write_register(DWORD hDC, WORD regaddr, WORD* regdatPt)
{
	GSPI_STATUS	result=0;	
	int			i;

	for (i=0 ; i<GSPI_MAX_REG_RETRY ; i++) {
		result = ssp_write_data_direct(hDC, regdatPt, regaddr, 1);
		if (result == GSPI_SUCCESS) {
			break;
		}
	}
	if (i == GSPI_MAX_REG_RETRY) {
		GSPIMSG(ERRMSG, (L"%s, Write register(%xh) timeout \n", TEXT(__FUNCTION__), regaddr));
		result = GSPI_TIMEOUT;
	}

	return result;
}


///
/// ssp_read_data: Read the data from SSP interface
/// Input: 
///		hDC - the context returned from SSP_Init
///		datPt - data buffer
///		size - size of the data buffer
///	Output:
///		none
///	Return: 
///		0 - success
///		-1 - failure
GSPI_STATUS ssp_read_data(DWORD hDC, WORD* datPt, WORD reg, WORD nword)
{
	GSPI_STATUS	result=0;
	int			i;

	for (i=0 ; i<GSPI_MAX_REG_RETRY ; i++) {
		result = ssp_read_data_direct(hDC, datPt, reg, nword, g_spi_dummy_clk_data);
		if (result == GSPI_SUCCESS) {
			break;
		}
	}
	if (i == GSPI_MAX_REG_RETRY) {
		GSPIMSG(1, (L"%s, Read data(%xh) timeout \n", TEXT(__FUNCTION__), nword));
		result = GSPI_TIMEOUT;
	}

	return result;
}

///
/// ssp_write_data: Write the data from SSP interface
/// Input: 
///		hDC - the context returned from SSP_Init
///		datPt - data buffer
///		size - size of the data buffer
///	Output:
///		datPt - returned data buffer
///		size - size of the returned data buffer
///	Return:
///		0 - success
///		-1 - failure
GSPI_STATUS ssp_write_data(DWORD hDC, WORD* datPt, WORD reg, WORD nword)
{
	///Note: reg(0x24) = DATA_PORT
	GSPI_STATUS	result=0;
	
	int			i;

	for (i=0 ; i<GSPI_MAX_REG_RETRY ; i++) {
		///result = ssp_write_data_direct(hDC, datPt, 0x24, size);
		result = ssp_write_data_direct(hDC, datPt, reg, nword);
		if (result == GSPI_SUCCESS) {
			break;
		}
	}
	if (i == GSPI_MAX_REG_RETRY) {
		GSPIMSG(1, (L"%s, Read data(%xh) timeout \n", TEXT(__FUNCTION__), nword));
		result = GSPI_TIMEOUT;
	}

	return result;
}

///===========================================
int pxa_read_intstate(DWORD hDC)
{

	DWORD			resval=0;

	return resval;
}
///===========================================

static BOOLEAN dev_ist(PSSP_HARDWARE_CONTEXT	pHC)
{


//return TRUE;



	#if (USE_DEVIRQ == 0)
	if (pHC->DriverShutdown == TRUE) {
		return FALSE;
	}
///	if (g_fmDnRdy == FALSE) {
		///Firmware has not been downloaded. It's impossible to have an interrupt.
///		return FALSE;
///	}

	/// If there is a pending intrrupt
	//{
	//WORD	ucHostIntStatus;

	///Note: HCR_HOST_INT_STATUS_REGISTER = 0x5c

⌨️ 快捷键说明

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