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

📄 spi.cpp

📁 CAN总线驱动程序
💻 CPP
字号:
#include "stdafx.h"
#include "spi.h"
#include <pkfuncs.h>


SPI_CTRL_BLK_t SPI_CtrlBlk;


BOOL SPI_Init(UINT8 port)
{
	UINT32 irq = IRQ_SPI0;
	DWORD dwErr;
	PUCHAR  pVMem;
    BOOL    bMapReturn;

	SPI_CtrlBlk.port = port;
  
    // reserve space for SPI
    pVMem = (PUCHAR)VirtualAlloc(0, sizeof(S3C2440A_SPI_REG), MEM_RESERVE, PAGE_NOACCESS);     
	if (! pVMem) 
	{
        DEBUGMSG(1, (TEXT("Virtual Alloc ERROR: %d\r\n"), GetLastError()));
		return FALSE;
    }

    // map in SPI registers
    bMapReturn = VirtualCopy( pVMem,
                                  (LPVOID)(S3C2440A_BASE_REG_PA_SPI >> 8),
                                  sizeof(S3C2440A_SPI_REG),
                                  PAGE_READWRITE | PAGE_NOCACHE |PAGE_PHYSICAL);
    if (! bMapReturn) 
	{
        DEBUGMSG(1, (TEXT("Virtual Copy ERROR for SPI regs: %d\r\n"), GetLastError()));
        return FALSE;
    }
    SPI_CtrlBlk.pSPIReg = (volatile S3C2440A_SPI_REG*)(pVMem);

	// reserve space for GPIO
    pVMem = (PUCHAR)VirtualAlloc(0, sizeof(S3C2440A_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);    
	if (! pVMem) 
	{
        DEBUGMSG(1, (TEXT("Virtual Alloc ERROR: %d\r\n"), GetLastError()));
		return FALSE;
    }
 
    // map in GPIO registers
    bMapReturn = VirtualCopy(pVMem,
                                 (LPVOID)(S3C2440A_BASE_REG_PA_IOPORT >> 8),
                                 sizeof(S3C2440A_IOPORT_REG),
                                 PAGE_READWRITE | PAGE_NOCACHE |PAGE_PHYSICAL);
    if (! bMapReturn) 
	{
        DEBUGMSG(1, (TEXT("Virtual Copy ERROR for IOP regs: %d\r\n"),  GetLastError()));
        return FALSE;
    }
    SPI_CtrlBlk.pIOPReg = (volatile S3C2440A_IOPORT_REG*)(pVMem);        

	if (SPI_PORT_0 == SPI_CtrlBlk.port)
	{
		// Baud rate=PCLK/2/(SPPRE+1) and PCLK=50M
		SPI_CtrlBlk.pSPIReg->SPPRE0 = 0x04; 
		// Control register
		SPI_CtrlBlk.pSPIReg->SPCON0 = (0x01 << 5) // SMOD:interrupt
							| (0x01 << 4) // ENSCK
							| (0x01 << 3) // MSTR
							| (0x00 << 1) // CPOL/CPHA format A
							| (0x00 << 0); // NO TAGD
		// Master out keep
		SPI_CtrlBlk.pSPIReg->SPPIN0 = 0x01; 

        // Create rx event
        SPI_CtrlBlk.hRxEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

		// Enable interrupt
		if (! KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, 
				&irq, sizeof(UINT32), &SPI_CtrlBlk.SPI_Intr, sizeof(UINT32), NULL))
		{
			DEBUGMSG(1, (TEXT("ERROR: Failed to request the IIC sysintr.\r\n")));
            return FALSE;
		}

        // Initialize the interrupt
        if( !InterruptInitialize(SPI_CtrlBlk.SPI_Intr, SPI_CtrlBlk.hRxEvent, NULL, 0) ) 
        {
            dwErr = GetLastError();
            DEBUGMSG(1,(TEXT("I2C_Init ERROR: Unable to initialize interrupt: %u\r\n"), dwErr));
            return FALSE;
        }

/*        // Create the IST
        if (! (SPI_CtrlBlk.htSPIThread = CreateThread(NULL, 
											0, 
											(LPTHREAD_START_ROUTINE)SPI_IntrThread, 
											(LPVOID)&SPI_CtrlBlk, 
											0, 
											NULL)))
        {
            dwErr = GetLastError();
            DEBUGMSG(ZONE_ERR,(TEXT("I2C_Init ERROR: Unable to create IST: %u\r\n"), dwErr));
            goto _init_error;
        }
*/

	}

	return TRUE;
}

/*
static DWORD WINAPI SPI_IntrThread(LPVOID pContext)
{
	DWORD dwRet;
	return 0;
}
*/

BOOL SPI_Open(UINT8 dev)
{
	if (SPI_DEVICE_00 == dev)
	{
		// nSS for enable slave
		SPI_CtrlBlk.pIOPReg->GPBDAT &= ~SPI_nSS_0;
		SPI_CtrlBlk.pIOPReg->GPBDAT |= SPI_nSS_1;
	}
	else if (SPI_DEVICE_01 == dev)
	{
		SPI_CtrlBlk.pIOPReg->GPBDAT &= ~SPI_nSS_1;
		SPI_CtrlBlk.pIOPReg->GPBDAT |= SPI_nSS_0;
	}

	return TRUE;		
}

BOOL SPI_Close(UINT8 dev)
{
	if (SPI_DEVICE_00 == dev)
	{
		// nSS for enable slave
		SPI_CtrlBlk.pIOPReg->GPBDAT |= SPI_nSS_0;
	}
	else if (SPI_DEVICE_01 == dev)
	{
		SPI_CtrlBlk.pIOPReg->GPBDAT |= SPI_nSS_1;
	}
	else
	{
		SPI_CtrlBlk.pIOPReg->GPBDAT |= SPI_nSS_0;
		SPI_CtrlBlk.pIOPReg->GPBDAT |= SPI_nSS_1;
	}

	return TRUE;		
}

BOOL SPI_Deinit(UINT8 port)
{
	if (SPI_CtrlBlk.pSPIReg)
		VirtualFree((PVOID)SPI_CtrlBlk.pSPIReg, 0, MEM_RELEASE);
	if (SPI_CtrlBlk.pIOPReg) 
		VirtualFree((PVOID)SPI_CtrlBlk.pIOPReg, 0, MEM_RELEASE);

	CloseHandle(SPI_CtrlBlk.hRxEvent);
	CloseHandle(SPI_CtrlBlk.hSPIThread);

	return TRUE;
}

INT32 SPI_Tranceive(UINT8 * send, UINT8 * recv, UINT8 len)
{
    RETAILMSG (1, (TEXT("+ ")TEXT(__FUNCTION__)TEXT("\r\n")));

	UINT8 i;
	DWORD dwRet;

	for (i = 0; i < len; i++)
	{
		if (SPI_CtrlBlk.pSPIReg->SPSTA0 & SPSTA_REDY)
		{
			if (send)
				SPI_CtrlBlk.pSPIReg->SPTDAT0 = send[i];
			else
				SPI_CtrlBlk.pSPIReg->SPTDAT0 = 0xff;

			dwRet = WaitForSingleObject(SPI_CtrlBlk.hRxEvent, SPI_RX_DELAY);
			
			InterruptDone(SPI_CtrlBlk.SPI_Intr);

			if (dwRet == WAIT_TIMEOUT)
			{
				RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT(" %d \r\n"),  GetLastError() ));
				return 0;
			}

			if (! recv)
				recv[i] = SPI_CtrlBlk.pSPIReg->SPRDAT0;
		}
	}

    RETAILMSG (1, (TEXT("- ")TEXT(__FUNCTION__)TEXT("\r\n")));

	return len;
}


⌨️ 快捷键说明

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