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

📄 spi.cpp

📁 一个基于windows mobile 的GPS 接受IC 驱动程序。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// GPS_SPI_VERSION_MINOR      88
    // Options: Enable stats; enable traces; disable debugs; long int-off
    // Trace extra int_acks
    // All time reporting uses glReportTime().
    // Change spiFormatTime() to glFormatTime().
    // Add "long int off" during SPI device driver operations.
    //
    //  RESULTS:
    //
    //  Performance is very good - 1-way latency is steady at 72 msec
    //  Read/Write times are 20 times faster.
    //  But interrupt off time is high: 251 usec to send 10 bytes.
    //  

// GPS_SPI_VERSION_MINOR      87
    // Report extra int_acks in the stats.
    // Fixed ISR time reporting.
    // Fixed intack suppression flag bug, and:
    // after 25 empty INT_ACKs, give an extra INT_ACK.
    //
    //  RESULTS:
    //
    // See 2 intack timeouts over a long test period.
    // Very efficient use of interrupt/event.
    // Very good performance.
    //

// GPS_SPI_VERSION_MINOR      86
    // Use the last read/write SR if we like it.
    // Change trace.cpp
    // Suppress extra int_acks.
    // Fixed ISR time reporting.
    //
    //  RESULTS:
    //
    // Works with low latency, Interrupt effectiveness is very good.
    // INT_ACK are suppressed
    // ISR time results are confusing
    // There seems to be a lot more effective timeouts than
    // are accounted for in the statistics.
    // The SPI_Write() time tracks the inter-write time too
    // closely:  this is because the inter-write time includes
    // the write() time.
    // Loses the INTERRUPT after a while.

// GPS_SPI_VERSION_MINOR      85
    // Enable stats/disable traces/disable debugs
    // Improve ISR reports.
    //
    // SPI_Write()
    // - remove one check: IsBadReadPtr(pBuf, Count)
    // - SetLastError(0);
    // SPI_Write_Bytes() - change to Sleep(1) when getting size to send.
    // SPI_Write_Bytes() use the most recent status if we have a
    //              status we like. Only read the status if we hate
    //              what we see (or if we didn't have a status).
    // SPI_Read_Bytes() same thing aas SPI_Write_Bytes().
    //
    //  RESULTS:
    //
    // Works with low latency, but interrupt effectiveness is low.
    // Too many INT_ACK.
    // ISR timing looks off.

// GPS_SPI_VERSION_MINOR      84
    // Enable stats/disable traces/disable debugs
    // Improve stats reports.
    // Eliminate pause/resume IST.
    // Remove retry from SPI_Read().
    // Fix totalInterrupts stats
    //      WORKS!!!  VERY WELLLLLLLL !!!!!
    // Latency is very low
    // Gets an autonomous fix indoors.

// GPS_SPI_VERSION_MINOR      83
    // Enable stats/disable traces/disable debugs
    // Minor spiFormatTime() changes.
    // Major addition to the tracing - added statistics for read/write/intack
    // Improve stats reports.
    // Works.

// GPS_SPI_VERSION_MINOR      82
    // Disable traces.
    // Minor spiFormatTime() changes.
    // Major addition to the tracing - added statistics for read/write/intack
    // Untested

// GPS_SPI_VERSION_MINOR      81
    // Traces off.
    // Call INTERRUPTS_OFF1() once.
    // Report time of a 60 status.
    // See a SPI bus interruption problem every few seconds;
    // but not all cause the underrun.

// GPS_SPI_VERSION_MINOR      80
    // Move the CHIP_ON inside the protected region - for SEND_CMD, etc.
    // Call INTERRUPTS_OFF1() twice.
    // Unify the polling/interrupt done code.
    // Added more interrupt enable commands.
    // Appear to be a SPI bus disruption even if interrupts are off.

// GPS_SPI_VERSION_MINOR      79
    // Move the CHIP_ON inside the protected region.
    // Trace - don't disable upon error.
    // Error messages - add more text.
    // SPI_IST  - use prio 100.
    // SPI_XFER - use SPI_IST+2.
    // Fewer 0x60 errors, but still have 1.
    // More events processed.

// GPS_SPI_VERSION_MINOR      78
    // Same as v1.77 except debugs are disabled.
    // Works.

// GPS_SPI_VERSION_MINOR      77
    // Revive gpsChipsetID.
    // Suppress interrupt restore until after GPSCT has decided to start
    // waiting (with a timeout) for more activity from the chipset.
    // Split the GPS device ID to a separate function.
    // Made the SPI done interrupt an option.
    // Works.

// GPS_SPI_VERSION_MINOR      76
    // Revert to Sleep(1) when waiting for SPI read completion.
    // Change speed to 400 KHz (was 128 KHz)
    // Works fine.

// GPS_SPI_VERSION_MINOR      75
    // Sleep(0) when waiting for SPI read completion.
    // Removed dead code.
    // Results:  sleep(0) made the SPI test very fast, but
    //           made the UI sluggish.


#define T_LABEL_MACRO(maj,min)  _T("#@(#)GpsSpiBulverde ") \
                                _T(#maj)     _T(".") \
                                _T(#min)     _T(" built ") \
                                _T(__DATE__) _T(" ") \
                                _T(__TIME__) _T(" ") \
                                _T(OPT_DONE_MSG) \
                                _T(OPT_PRIO_MSG) _T(" ") \
                                _T(OPT_GPIO)

#define LABEL_MACRO(maj,min) "#@(#)GpsSpiBulverde " #maj "." #min \
                             " built " __DATE__ " " __TIME__ \
                             " " OPT_DONE_MSG " " OPT_PRIO_MSG " " OPT_GPIO

#define T_GPS_LABEL(maj,min)   T_LABEL_MACRO(maj,min)
#define   GPS_LABEL(maj,min)     LABEL_MACRO(maj,min)

static const TCHAR t_driverLabel[] = {T_GPS_LABEL(GPS_SPI_VERSION_MAJOR,GPS_SPI_VERSION_MINOR)};
       const  char   driverLabel[] = {  GPS_LABEL(GPS_SPI_VERSION_MAJOR,GPS_SPI_VERSION_MINOR)};
const char* pDriverLabel = driverLabel;

//-----------------------------------------------------------------------------
//  Globals.
//----------------------------------------------------------------------------
#define CACHED_TO_UNCACHED_OFFSET	0x20000000
#define GPIO_OFFSET					0x00E00000
#define SSP3_OFFSET					0x01900000
#define CLK_OFFSET                  0x01300000      // Clock Manager
#define OST_OFFSET                  0x00A00000      // OS Timer Manager

#define PERIF_BASE_C_VIRTUAL		0x8C000000
#define PERIF_BASE_U_VIRTUAL		(PERIF_BASE_C_VIRTUAL + CACHED_TO_UNCACHED_OFFSET)
#define GPIO_BASE_U_VIRTUAL			(PERIF_BASE_U_VIRTUAL + GPIO_OFFSET)
#define SSP3_BASE_U_VIRTUAL			(PERIF_BASE_U_VIRTUAL + SSP3_OFFSET)
#define CLK_BASE_U_VIRTUAL			(PERIF_BASE_U_VIRTUAL + CLK_OFFSET)
#define OST_BASE_U_VIRTUAL			(PERIF_BASE_U_VIRTUAL + OST_OFFSET)

volatile XLLP_GPIO_T*   v_pGPIORegs  = (XLLP_GPIO_T   *)GPIO_BASE_U_VIRTUAL;
volatile XLLP_SSP_REGS* v_pSPIRegs   = (XLLP_SSP_REGS *)SSP3_BASE_U_VIRTUAL;	//gpSsp3hw
volatile XLLP_CLKMGR_T* v_pClockRegs = (XLLP_CLKMGR_T *)CLK_BASE_U_VIRTUAL;		//pSpiClock

//-----------------------------------------------------------------------------
//  Forward declarations - provided by this device driver.
//-----------------------------------------------------------------------------

static BOOL  SPI_AllocReg(SPI_DEVICE_CONTEXT* pDev);
SPI_EXPORT BOOL SPI_Deinit(DWORD hDeviceContext);
static DWORD SPI_Isr(PVOID pArg);
extern bool spiDevClosed;
static void sspConfig(void);

//-----------------------------------------------------------------------------
//  Forward declarations - provided by the OS (ceddk.dll?)
//-----------------------------------------------------------------------------

//extern "C" BOOL InterruptInitialize(DWORD gpsIntr,
//							HANDLE h, PVOID arg, DWORD param);

/*******************************************************************************
********************************************************************************
**
**      Routines to be filled in by the customer
**
**  Please fill in these routines.
**  In cases where the routines are *not* required, the sample code
**  will return the error case.
**
********************************************************************************
*******************************************************************************/

//------------------------------------------------------------------------------
//
//          getMsisdn() - not required
//
// There are several possibilities to fill in the MSISDN
// See spiIoctl.h for all the choices.
//
// A BCD example is shown here.
//
// Nothing is needed for initial implementation, but this
// information is required for SUPL support.
//
//------------------------------------------------------------------------------

BOOL Customer_getMsisdnBcd(unsigned char* pBCD)
{
    // memcpy(pBCD, Customer_MSISDN_BUFFER, 8);
    return false;       // fill in the real stuff, please.
}

//------------------------------------------------------------------------------
//
//          getCellInfo() - not required
//
//------------------------------------------------------------------------------

BOOL Customer_getCellInfo(GLL_CID* cid)
{
    static int CI = 0;
    cid->MCC = 1;       // fill in the real stuff, please.
    cid->MNC = 2;
    cid->LAC = 3;
    cid->CI  = ++CI;
    return TRUE;       // test purposes only.
}

//------------------------------------------------------------------------------
//
//          reallyGoodTime() - not required
//
//  For best operation, the customer should provide a seconds counter that:
//  a)  Is pretty accurate.
//  b)  Is not changed when the user changes the time.
//  c)  Is not changed when the user changes the time zone.
//  d)  Continues counting when the device is turned off.
//  e)  Starts over at zero when the device is "hard" reset.
//
//  There are three choices:
//
//  A)  Do not provide Customer_reallyGoodTime().  Instead,
//      provide time on the GPS device itself.  This has hardware and
//      system consequences to be discussed with the Global Locate FAE.
//      << This is the best choice, and is assumed in this driver >>
//
//  B)  Do not provide Customer_reallyGoodTime().  Instead,
//      allow use of the device time, but beware that time has changed,
//      and accept the poor GPS performance.  The GpsctService will detect
//      the time change, and subsequent position fixes can have poor
//      performance.
//      << This is the worst choice, and is used only in demonstration
//          integrations, not for production. >>
//
//  C)  Implement Customer_reallyGoodTime().
//      << This is also a good choice as it simplifies the hardware and
//         software, but can require additional software development by
//         the customer. >>
//
//------------------------------------------------------------------------------

DWORD Customer_reallyGoodTime(void)
{
    return 0;
}

/*******************************************************************************
********************************************************************************
**
**      Device Driver Public Entry Points.
**
**  These subroutines satisfy the requirements of the Microsoft
**  device driver interface.
**
********************************************************************************
*******************************************************************************/

//-----------------------------------------------------------------------------
//
//                  SPI_Init()
//
//  Init access to the hardware.
//  Init access to the ISR.
//  Init the ring buffers.
//  Resume control of the GPIO.
//
//-----------------------------------------------------------------------------

#ifdef  SPI_DONE_INTERRUPT          // Use ISR to detect the SPI done
HANDLE ghRxDone = 0;
#endif

SPI_EXPORT DWORD
SPI_Init(LPCTSTR pContext, LPCVOID lpvBusContext)
{
    GL_ERROR((TEXT("SPI_Init()/%d %s\n\r"), __LINE__,
                                                t_driverLabel, driverLabel));

	// allocate our device context
    SPI_DEVICE_CONTEXT* pDev = (SPI_DEVICE_CONTEXT *)malloc(sizeof(SPI_DEVICE_CONTEXT));
	pDev->ctor(DEBUG);

    //-------------------------------------------------------------------------
    //      GPIO Configuration
    //
    // Set the Bulverde GPIO to drive the GPS_PWR_EN signal.
    // Set the Bulverde GPIO to accept the GPS interrupt signal.
    // Set the Bulverde clock to drive the SSP3 port for SPI.
    // - all these things are done by the OS or other device drivers.
    //
	// You can see the Bulverde CPU Spec. 3-100 to learn about the GPIOs.
    //
    //-------------------------------------------------------------------------

#ifdef GPS_GPIO_RESET_EXISTS 
	v_pGPIORegs->GPSR_RESET  = GPS_GPIO_RESET_EXISTS;
	v_pGPIORegs->GPDR_RESET |= GPS_GPIO_RESET_EXISTS;
	GL_PRINT((MSG("GPS Reset Enable!! 0x%x\r\n"),GPS_GPIO_RESET_EXISTS));
	Sleep(1);
#endif

#ifdef GPS_GPIO_POWER_EXISTS 
	v_pGPIORegs->GPSR_POWER  = GPS_GPIO_POWER_EXISTS;
	v_pGPIORegs->GPDR_POWER |= GPS_GPIO_POWER_EXISTS;
	GL_PRINT((MSG("GPS Power Enable!! 0x%x\r\n"),GPS_GPIO_POWER_EXISTS));
	Sleep(1);
#endif

#ifdef GPS_GPIO_STANDBY_EXISTS 
	v_pGPIORegs->GPSR_STANDBY  = GPS_GPIO_STANDBY_EXISTS;
	v_pGPIORegs->GPDR_STANDBY |= GPS_GPIO_STANDBY_EXISTS;
	GL_PRINT((MSG("GPS Power Enable!! 0x%x\r\n"),GPS_GPIO_STANDBY_EXISTS));
#endif

	Sleep(10);

    //-------------------------------------------------------------------------
    //      SSP Configuration
    //-------------------------------------------------------------------------

    sspConfig();

    rb__RingBufferInit();
    traceInit();
    pDev->mbIsrAllow = false;
    pDev->mIsrHandle = INVALID_HANDLE_VALUE;

#ifdef  _ENABLE_TRACE_
	XLLP_OST_T* pOST = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
    pGpsTimer = (volatile DWORD*) &pOST->oscr0;
#endif

    //-------------------------------------------------------------------------
    //
    //      ISR Init
    //
    //  1)  The interrupt from Mantaray/Hammerhead to Bulverde is used
    //      to shorten the HABI poll loop.  It is enabled only just before
    //      the HABI will be sleeping for 100 ms.
    //
    //-------------------------------------------------------------------------

    pDev->intackNeeded = false;
    pDev->mIsrHandle = CreateThread(NULL, 0,
                            (LPTHREAD_START_ROUTINE) SPI_Isr,
                            (LPVOID)pDev, 0, &pDev->mIsrThreadID);
    if (pDev->mIsrHandle == INVALID_HANDLE_VALUE)
    {
        GL_ERROR((TEXT("SPI_Init()/%d Cannot init gps ISR \n\r"), __LINE__));
        SPI_Deinit((DWORD)pDev);
        return 0;
    }

#ifdef  SPI_DONE_INTERRUPT
    //-------------------------------------------------------------------------
    //
    //      ISR Init
    //
    //  The interrupt from the Bulverde SPI3 device to the CPU.
    //  It is used to signal the end of SPI transfers of 3 to 16 bytes.
	//	1 or 2 byte transfers are polled directly.
    //
    //-------------------------------------------------------------------------

    pDev->mhRxDone = CreateEvent(NULL, FALSE, FALSE, NULL);
          ghRxDone = pDev->mhRxDone;

    if (!InterruptInitialize(SYSINTR_SSP3, pDev->mhRxDone, 0, 0))
    {
        GL_ERROR((TEXT("SPI_Init()/%d Cannot init spi ISR %d\n\r"),
                                                __LINE__, SYSINTR_SSP3));
        SPI_Deinit((DWORD)pDev);
        return 0;
    }
#endif

    //-------------------------------------------------------------------------
    //      GPS Device ID report
    //-------------------------------------------------------------------------
	// GetGpsDeviceID();

    GL_PRINT((MSG("SPI_Init()/%d 0x%x int %d\n\r"),__LINE__, pDev, SYSINTR_GPS));
    return (DWORD)pDev;
}

//-----------------------------------------------------------------------------
//
//                  sspConfig()
//
//  Init SSP3 port.
//
//-----------------------------------------------------------------------------

static void
sspConfig(void)
{
	v_pClockRegs->cken |= XLLP_CLKEN_SSP3;
	v_pClockRegs->oscc |= XLLP_OSCC_TOUT_EN;

	v_pSPIRegs->sscr0 = 0x00000000;

    //  Prior to 1.76:
	//v_pSPIRegs->sscr0  =  (XLLP_SSCR0_DSS_8BIT | XLLP_SSCR0_SCR_128K | XLLP_SSCR0_RIM | XLLP_SSCR0_TIM);

    //  Try this with v1.76:
	v_pSPIRegs->sscr0  =  (XLLP_SSCR0_DSS_8BIT | XLLP_SSCR0_SCR_400K | XLLP_SSCR0_RIM | XLLP_SSCR0_TIM);

	v_pSPIRegs->sscr0 &= ~(XLLP_SSCR0_EDSS     | XLLP_SSCR0_NCS      | XLLP_SSCR0_ECS);
	v_pSPIRegs->sscr1 = 0x00000000;
	v_pSPIRegs->ssitr = 0x00000000;
	v_pSPIRegs->ssto  = 0x00001000;
    GL_PRINT((MSG("sspConfig()/%d CR1 0x%x\n\r"),__LINE__, v_pSPIRegs->sscr1));
}

⌨️ 快捷键说明

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