/****************************************************************************** * LEGAL NOTICE * * * * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND * * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE * * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT * * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE * * OR DOCUMENTATION. * * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR * * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF * * THE LICENSE TERMS AS STATED. * * * ******************************************************************************/ /* Version: 1.8.9\3686 */ /* Build : 13 */ /* Date : 12/08/2012 */ /** \file \brief CellGuide CGsnap driver core logic (OS & CPU independed) \attention This file should not be modified. If you think something is wrong here, please contact CellGuide */ #include #include "CgxDriverCore.h" #include "CgCpu.h" #include "CgCpuOs.h" #include "platform.h" #include "CgxDriverPlatform.h" #include "CgxDriverOs.h" #include "CgBuildNumber.h" #include "CgVersion.h" #include "CgxDriverCoreCommon.h" /** Driver version structure \note this structure is filled automatically on build time, by CellGuide build machine */ const TCgVersion gCgDriverVersion = { CG_BUILD_VERSION, /**< Software Version number (Text)*/ CG_BUILD_ORIGINATOR, /**< Build Originator name (Text)*/ CGX_PLATFORM_NAME, /**< Platform Name (Text), as specified in platform.h file */ CG_BUILD_NUMBER, /**< Unique Build Number (Text) - automatically assigned by build machine*/ CG_BUILD_DATE, /**< Build Date (Text)*/ CG_BUILD_TIME, /**< Build Time (Text)*/ CG_BUILD_MODE /**< Build Mode (Text) - Release/Test/Debug */ }; extern void gps_chip_power_on(void); extern void gps_chip_power_off(void); extern void gps_gpio_request(void); #define CG_MATH_ALIGNMENT(__var__,__base__) __var__ = (__base__) * ((U32)(((__var__) + ((__base__)/2)) / (__base__))) TCgCpuDmaTask gChunksList[MAX_DMA_TRANSFER_TASKS]; /**< DMA tasks list */ S32 CgxDriverSnapLengthExtraBytes = 0; extern U32 CGCORE_BASE_ADDR; /** CGsnap GPO register offset */ const U32 CGCORE_REG_OFFSET_GPO = 0x00000040; /** CGsnap version register offset */ const U32 CGCORE_REG_OFFSET_VERSION = 0x00000044; /** CGsnap interrupt register offset (KAGPSRawInt)*/ const U32 CGCORE_REG_RAW_INT = 0x00000080; /** CGsnap Soft_CMD register offset */ const U32 CGCORE_REG_OFFSET_SOFT_CMD = 0x000000CC; const U32 CGCORE_SOFT_CMD_POWER_DOWN = 0xFDB96420; /** CGsnap reset register offset */ const U32 CGCORE_REG_OFFSET_CORE_RESETS = 0x000000FC; #ifndef RF_POWER_UP_VAL #define RF_POWER_UP_VAL (0) // ACLYS requires '0' for PU #endif #ifdef CGCORE_ACCESS_VIA_SPI extern void init_spi_block_var(void); static unsigned int block_num; #endif bool flag_power_up = 0; TCgReturnCode CgxDriverTcxoControl(u32 aEnable); #define CGCORE_ENABLE_CORE (0x00000000) #define CGCORE_ENABLE_TCXO (0x00000001) #define CGCORE_ENABLE_RTC (0x00000002) #define CGCORE_ENABLE_BS (0x00000003) #define CGCORE_RF_POWER_UP_POL (0x00000004) // RF Power up polarity. "Power UP" GPO[0] value is determined by this bit's value. // (if bit is '1', during power up, the IP will output '1', and during power down, // it will output '0'. When this bit is '0', the output is reversed) const U32 CGCORE_CORE_RESETS_ENABLE = ((1<constructionRc = rc; // For later reference (if needed by application) pState->flags.resume = FALSE; #ifdef CGCORE_ACCESS_VIA_SPI gps_chip_power_off(); #endif return rc; } TCgReturnCode CgxDriverPowerUp(void) { TCgReturnCode rc = ECgOk; U32 version = 0; // In order to power up the CGsnap, do a dummy access rc = CGCORE_READ_REG(CGCORE_REG_OFFSET_VERSION, &version ); return rc; } TCgReturnCode CgxDriverPowerDown(void) { TCgReturnCode rc = ECgOk; // Write software power-down command to CGsnap rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_SOFT_CMD, CGCORE_SOFT_CMD_POWER_DOWN ); return rc; } #ifdef CGCORE_ACCESS_VIA_SPI unsigned int get_block_num(void ) { return block_num; } #endif #if 0 //gaole add void CgCoreReleaseRes(void) { printk("\n gaole: run to CgCoreReleaseRes \n"); memset(gChunksList,0,sizeof(TCgCpuDmaTask)*MAX_DMA_TRANSFER_TASKS); #ifdef CGCORE_ACCESS_VIA_SPI block_num = 0; #endif } void CgGpsReset(void) { CGCORE_WRITE_REG( 0x00000038, 0x0); CGCORE_WRITE_REG( 0x0000003c, 0x0); CGCORE_WRITE_REG( CGCORE_REG_OFFSET_CORE_RESETS, CGCORE_CORE_RESETS_ENABLE); } #endif /* split blocks to chunks last chunk might be small last chunk generate app event start of block aligned to chunk size */ TCgReturnCode CgxDriverPrepareRecieve( TCgxDriverState *pState, unsigned char *apBuf, U32 aBufPhys, U32 aBufSize, unsigned long aLength, unsigned long aBlockLength, TCgByteOrder aByteOrder) { DBG_FUNC_NAME("CgxDriverPrepareRecieve") TCgReturnCode rc = ECgOk; U32 blockIndex = 0; U32 chunksInBlock = 0; U32 chunkSize = 0; U32 length = aLength + CgxDriverSnapLengthExtraBytes; // Potential patch U32 numOfBlocksInBuffer = 0; memset(gChunksList,0,sizeof(TCgCpuDmaTask)*MAX_DMA_TRANSFER_TASKS); DBGMSG1("buffer v-address = 0x%x", apBuf); DBGMSG1("start address value = 0x%x", *((U32*)apBuf) ); DBGMSG1("dest address value = 0x%x", *((U32*)apBuf + 128) ); pState->transfer.blockSize = ((aBlockLength == 0) || (length < aBlockLength)) ? length : aBlockLength; /*bxd modify for not limted to 512k Bytes each block*/ chunkSize = pState->transfer.blockSize; //chunkSize = MIN(MAX_DMA_CHUNK_SIZE, pState->transfer.blockSize); chunksInBlock = pState->transfer.blockSize / chunkSize; DBGMSG3("Requested %d bytes, Block=(%d bytes,%d chunks)", length, pState->transfer.blockSize, chunksInBlock); DBGMSG1("Maximum DMA chunk size is set to %d bytes", chunkSize); pState->flags.overrun = FALSE; pState->transfer.cancel.request = FALSE; pState->transfer.cancel.onByte = 0; pState->transfer.cancel.onChunk = 0; pState->transfer.done = 0; pState->transfer.originalBuffer = apBuf; pState->transfer.bufferPhys = pState->buffer.physAddr; pState->transfer.byteOrder = aByteOrder; pState->transfer.bytes.required = length; pState->transfer.bytes.received = 0; pState->transfer.blocks.required = (length + pState->transfer.blockSize - 1) / pState->transfer.blockSize; #ifdef CGCORE_ACCESS_VIA_SPI block_num = pState->transfer.blocks.required; #endif DBGMSG1("%d blocks required", pState->transfer.blocks.required); pState->transfer.lastBlockSize = length - (pState->transfer.blocks.required - 1) * pState->transfer.blockSize; DBGMSG1("last block size: %d bytes", pState->transfer.lastBlockSize); pState->transfer.blocks.received = 0; pState->transfer.chunks.required = 0; pState->transfer.chunks.received = 0; pState->transfer.chunks.active = 0; // split snap to blocks ////////////////////////////////////////////////////////////////////////// if (pState->transfer.blocks.required * chunksInBlock > MAX_DMA_TRANSFER_TASKS) { DBGMSG2("ERROR! too many chunks! %d > %d", pState->transfer.blocks.required * chunksInBlock, MAX_DMA_TRANSFER_TASKS); return ECgErrMemory; } numOfBlocksInBuffer = aBufSize / pState->transfer.blockSize; DBGMSG2("aBufSize = %d, blockSize = %d", aBufSize, pState->transfer.blockSize ); for(blockIndex = 0; blockIndex < pState->transfer.blocks.required; blockIndex++) { // Init the snap's blocks' offsets pState->transfer.bufferOffset[blockIndex] = pState->transfer.blockSize * (blockIndex % numOfBlocksInBuffer); // roll-over to start of buffer, // if we reached end of buffer. //DBGMSG2("buffer[%d] = 0x%08X", blockIndex, pState->transfer.bufferPhys + pState->transfer.bufferOffset[blockIndex]) } // split blocks to chunks ////////////////////////////////////////////////////////////////////////// for(blockIndex = 0; blockIndex < pState->transfer.blocks.required; blockIndex++) { U32 chunkIndex = 0; U32 more, dest; more = (blockIndex == (pState->transfer.blocks.required-1)) ? pState->transfer.lastBlockSize : pState->transfer.blockSize; dest = pState->transfer.bufferPhys + pState->transfer.bufferOffset[blockIndex]; // DBGMSG4("Block %02d/%02d: % 6d bytes @ 0x%08X", blockIndex + 1, pState->transfer.blocks.required, for(chunkIndex = 0; chunkIndex < chunksInBlock-1; chunkIndex++) { U32 size = MIN(more, chunkSize); if ((more - size) < chunkSize) break; gChunksList[pState->transfer.chunks.required].address = dest; gChunksList[pState->transfer.chunks.required].length = size; more -= size; // DBGMSG5("chunk %02d/%02d in block: length %d bytes @ 0x%08X (%d more)", chunkIndex + 1, chunksInBlock, dest += size; pState->transfer.chunks.required++; } // last chunk gChunksList[pState->transfer.chunks.required].address = dest; gChunksList[pState->transfer.chunks.required].length = more; DBGMSG3("last chunk out of %02d in block: % 6d bytes @ 0x%08X", chunksInBlock, more, dest); pState->transfer.chunks.required++; } DBGMSG1("%d chunks required", pState->transfer.chunks.required); if (length > pState->transfer.blockSize * pState->transfer.blocks.required) { // there are leftovers U32 more = length - pState->transfer.blockSize * pState->transfer.blocks.required; U32 dest = pState->transfer.bufferPhys + pState->transfer.bufferOffset[pState->transfer.blocks.required]; DBGMSG4("Extra Block % 2d/% 2d: % 6d bytes @ 0x%08X", pState->transfer.blocks.required, pState->transfer.blocks.required, more, dest); for (; (more > 0) && (pState->transfer.chunks.required < MAX_DMA_TRANSFER_TASKS); pState->transfer.chunks.required++) { U32 size = MIN(more, chunkSize); gChunksList[pState->transfer.chunks.required].address = dest; gChunksList[pState->transfer.chunks.required].length = size; more -= size; dest += size; DBGMSG4("chunk % 4d: % 4d bytes @ 0x%08X (%d bytes left)", pState->transfer.chunks.required + 1, size, dest, more); } DBGMSG1("%d chunks required", pState->transfer.chunks.required); } // setup 1st DMA chunk #ifndef CGCORE_ACCESS_VIA_SPI rc = CgCpuDmaSetupFromGps(gChunksList, pState->transfer.chunks.required, CG_DRIVER_DMA_CHANNEL_READ, CGCORE_BASE_ADDR + 0x00000070); rc = CgCpuDmaStart(CG_DRIVER_DMA_CHANNEL_READ); #else // rc =CgxCpuSpiReadData(); #endif return rc; } TCgReturnCode CgxDriverIsReadCanceled(TCgxDriverState *pState) { DBG_FUNC_NAME("CgxDriverIsReadCanceled") TCgReturnCode rc = ECgOk; // Check if snap was unconditionally canceled if (pState->transfer.cancel.request && (pState->transfer.bytes.received > pState->transfer.cancel.onByte)) { CGCoreReset(CGCORE_ENABLE_CORE); CgCpuDmaStop(CG_DRIVER_DMA_CHANNEL_READ); return ECgCanceled; } // Check if we have reached the cancel point if (pState->transfer.cancel.request) { U32 curDmaCount = 0; U32 requestedDmaCount = 0; rc = CgCpuDmaRequestedCount(CG_DRIVER_DMA_CHANNEL_READ, &requestedDmaCount); // how many bursts requested to receive DBGMSG1("requestedDmaCount = %d", requestedDmaCount); rc = CgCpuDmaCurCount(CG_DRIVER_DMA_CHANNEL_READ, &curDmaCount); // how many bursts left to receive DBGMSG1("curDmaCount = %d", curDmaCount); DBGMSG2("%d >= %d ? ==> canceled", pState->transfer.bytes.received + (requestedDmaCount - curDmaCount) , pState->transfer.cancel.onByte); if (pState->transfer.bytes.received + (requestedDmaCount - curDmaCount) >= pState->transfer.cancel.onByte) { CGCoreReset(CGCORE_ENABLE_CORE); CgCpuDmaStop(CG_DRIVER_DMA_CHANNEL_READ); return ECgCanceled; } } return ECgOk; } TCgReturnCode CGCoreEnable(U32 aUnitToEnable) { DBG_FUNC_NAME("CGCoreEnable") TCgReturnCode rc = ECgOk; U32 enableValue = 1; U32 coreResetsReg = 0; rc = CGCORE_READ_REG(CGCORE_REG_OFFSET_CORE_RESETS, &coreResetsReg); // DBGMSG1("Read coreResetsReg=0x%08X", coreResetsReg); REG_SET1(coreResetsReg, aUnitToEnable, enableValue); if (OK(rc)) rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_CORE_RESETS, coreResetsReg); DBGMSG1("Write [0x%08X]", coreResetsReg); return rc; } TCgReturnCode CGCoreDisable(U32 aUnitToDisable) { DBG_FUNC_NAME("CGCoreDisable") TCgReturnCode rc = ECgOk; U32 disableValue = 0; U32 coreResetsReg = 0; rc = CGCORE_READ_REG(CGCORE_REG_OFFSET_CORE_RESETS,&coreResetsReg); // DBGMSG1("Read coreResetsReg=0x%08X", coreResetsReg); REG_SET1(coreResetsReg, aUnitToDisable, disableValue); if (OK(rc)) rc = CGCORE_WRITE_REG(CGCORE_REG_OFFSET_CORE_RESETS,coreResetsReg); DBGMSG1("Write [0x%08X]", coreResetsReg); return ECgOk; } TCgReturnCode CGCoreReset(U32 aUnitToReset) { DBG_FUNC_NAME("CGCoreReset") TCgReturnCode rc = ECgOk; U32 coreResetsReg = 0; U32 coreResetsRegOld = 0; ////////////////// Core Disable ////////////// rc = CGCORE_READ_REG(CGCORE_REG_OFFSET_CORE_RESETS,&coreResetsReg); coreResetsRegOld = coreResetsReg; REG_SET1(coreResetsReg, aUnitToReset, 0); if (OK(rc)) rc = CGCORE_WRITE_REG(CGCORE_REG_OFFSET_CORE_RESETS,coreResetsReg); DBGMSG1("Write [0x%08X]", coreResetsReg); if (OK(rc)) rc = CgCpuDelay(CGCORE_RESET_DELAY); ////////////////// Core Enable ////////////// if (OK(rc)) rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_CORE_RESETS, coreResetsRegOld); DBGMSG1("Write [0x%08X]", coreResetsRegOld); return rc; } TCgReturnCode CgxDriverExecuteSpecific( void *pDriver, TCgxDriverState *pState, U32 aRequest, TCgDriverControl *pControl, TCgDriverStatus *pResults) { DBG_FUNC_NAME("CgxDriverExecuteSpecific") DBGMSG1("aRequest =%x",aRequest); switch (aRequest) { case CGX_IOCTL_INIT: DBGMSG("CGX_IOCTL_INIT"); // This is 1st time initialization, meaning the software is restarted, not resumed, so set the state accordingly. DBGMSG1("pState = 0x%x", pState); pState->flags.resume = FALSE; DBGMSG("after pState->flags.resume = FALSE;"); pResults->rc = CgxDriverInit(pDriver); break; case CGX_IOCTL_STOP: pResults->rc = CgxDriverDestroy(pDriver); break; case CGX_IOCTL_READ_REG: pState->transfer.cancel.request = FALSE; // Verify register is of the CGX_sat_ram group pResults->readReg.value = 0; DBGMSG1("readReg.offset %x ",pControl->readReg.offset); if ( pControl->readReg.offset >= CGCORE_REG_OFFSET_SAT_RAM && pControl->readReg.offset <= CGCORE_REG_OFFSET_SAT_RAM_LAST ) { // Write read command to the APB (9 bits of the register offset, with 0x80000000, as the read command) pResults->rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_APB_COMMAND, (0x000001FF & pControl->readReg.offset) | 0x80000000); // Wait 4 system clocks CgCpuDelay(100); // TODO : what is the actual period of this wait. Is it 4 system clocks? // Read data from the APB if (OK(pResults->rc)) pResults->rc = CGCORE_READ_REG( CGCORE_REG_OFFSET_APB_DATA, &pResults->readReg.value); } else { // It is not part of the CGX_sat_ram. Read register normaly, via the APB pResults->rc = CGCORE_READ_REG( pControl->readReg.offset, &pResults->readReg.value); } break; case CGX_IOCTL_WRITE_REG: pState->transfer.cancel.request = FALSE; // Write to CGsnap register pResults->rc = CGCORE_WRITE_REG( pControl->writeReg.offset, pControl->writeReg.value); // DBGMSG2("CGX_IOCTL_WRITE_REG *0x%08X = 0x%08X", CGCORE_BASE_ADDR_VA + pControl->writeReg.offset, pControl->writeReg.value); break; case CGX_IOCTL_PREPARE_RECEIVE: DBGMSG("CGX_IOCTL_PREPARE_RECEIVE"); // Prepare driver for massive data receive (snap) pState->transfer.cancel.request = FALSE; pResults->rc = CgxDriverPrepareRecieve(pState, pControl->read.buf, pControl->read.bufPhys, pState->buffer.length, pControl->read.alignedLength, pControl->read.blockLength, pControl->read.byteOrder); break; case CGX_IOCTL_STATUS: pResults->rc = pState->constructionRc; break; case CGX_IOCTL_RESUME_CLEAR: DBGMSG("CGX_IOCTL_RESUME_CLEAR!"); pState->flags.resume = FALSE; pState->transfer.cancel.request = FALSE; break; case CGX_IOCTL_RESET: DBGMSG1("CGX_IOCTL_RESET level %d", pControl->reset.resetLevel); pState->transfer.cancel.request = FALSE; switch( pControl->reset.resetLevel ) { case 0: // Full reset #if 0 if (OK(pResults->rc)) pResults->rc = CgCpuIPMasterResetOn(); if (OK(pResults->rc)) pResults->rc = CgCpuDelay(CGCORE_RESET_DELAY); if (OK(pResults->rc)) pResults->rc = CgCpuIPMasterResetClear(); #endif if (OK(pResults->rc)) pResults->rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_CORE_RESETS, CGCORE_CORE_RESETS_ENABLE); break; case 1: // Semi reset if (OK(pResults->rc)) pResults->rc = CGCoreReset(CGCORE_ENABLE_CORE); #ifdef CGCORE_ACCESS_VIA_SPI init_spi_block_var(); #endif break; case 2: // CPU reset break; default : // Semi reset, also. if (OK(pResults->rc)) pResults->rc = CGCoreReset(CGCORE_ENABLE_CORE); break; } pResults->rc = CgCpuDmaStop(CG_DRIVER_DMA_CHANNEL_READ); break; case CGX_IOCTL_COUNTER_RESET: DBGMSG("CGX_IOCTL_COUNTER_RESET!"); pResults->rc = CgCpuDmaStop(CG_DRIVER_DMA_CHANNEL_READ); if (OK(pResults->rc)) pResults->rc = CGCoreReset(CGCORE_ENABLE_TCXO); break; case CGX_IOCTL_POWER_DOWN: DBGMSG("CGX_IOCTL_POWER_DOWN!"); flag_power_up = 0; pResults->rc = CgxDriverPowerDown(); if (OK(pResults->rc)) pResults->rc = CgxDriverRFPowerDown(); break; case CGX_IOCTL_POWER_UP: flag_power_up = 1; pState->transfer.cancel.request = FALSE; pResults->rc = CgxDriverPowerUp(); if (OK(pResults->rc)) pResults->rc = CgxDriverRFPowerUp(); break; case CGX_IOCTL_POWER_OFF : pResults->rc = CgxDriverPowerOff(); break; case CGX_IOCTL_POWER_ON : pResults->rc = CgxDriverPowerOn(); break; case CGX_IOCTL_GPIO_SET: //DBGMSG2("CGX_IOCTL_GPIO_SET 0x%08X = %d", pControl->GPIO.code, pControl->GPIO.out); if (pControl->GPIO.out) pResults->rc = CgCpuGpioSet(pControl->GPIO.code); else pResults->rc = CgCpuGpioReset(pControl->GPIO.code); //rc = CgxDriverDebugGpio((int)pControl->GPIO.code, (int)pControl->GPIO.out); break; case CGX_IOCTL_GPIO_GET: //DBGMSG1("CGX_IOCTL_GPIO_GET 0x%08X", pControl->GPIO.code); //pResults->GPIO.in = 0x5a5a; //DBGMSG2("CGX_IOCTL_GPIO_GET before 0x%08X=0x%08X", pControl->GPIO.code, pResults->GPIO.in) pResults->rc = CgCpuGpioGet(pControl->GPIO.code, (int *)&(pResults->GPIO.val)); pResults->GPIO.code = pControl->GPIO.code; //DBGMSG2("CGX_IOCTL_GPIO_GET after 0x%08X=0x%08X", pControl->GPIO.code, pResults->GPIO.in) //rc = CgxDriverDebugGpioRead((int)pResults->GPIO.code, (int*)&pResults->GPIO.in); break; case CGX_IOCTL_GET_VERSION: memcpy(pResults->version.buildVersion, gCgDriverVersion.buildVersion, sizeof(pResults->version.buildVersion)); memcpy(pResults->version.buildMode, gCgDriverVersion.buildMode, sizeof(pResults->version.buildNumber)); memcpy(pResults->version.buildNumber, gCgDriverVersion.buildNumber, sizeof(pResults->version.buildNumber)); memcpy(pResults->version.buildTime, gCgDriverVersion.buildTime, sizeof(pResults->version.buildTime)); memcpy(pResults->version.buildDate, gCgDriverVersion.buildDate, sizeof(pResults->version.buildDate)); break; case CGX_IOCTL_CANCEL_RECEIVE: DBGMSG1("Request cancel on byte %d", pControl->cancel.onByteCount); // set up receive abort flag. // the flag is cleared be prepare receive command if (pControl->cancel.onByteCount > (U32)CgxDriverSnapLengthExtraBytes) { pState->transfer.cancel.onByte = pControl->cancel.onByteCount - CgxDriverSnapLengthExtraBytes; CG_MATH_ALIGNMENT((pState->transfer.cancel.onByte), NUMBER_1K); DBGMSG1("cancel on Byte: 0x%08X", pState->transfer.cancel.onByte); } else { pState->transfer.cancel.onByte = 0; // Cancel snap req immediately } pState->transfer.cancel.request = TRUE; DBGMSG1("cancel on Byte: 0x%08X", ((pState->transfer.cancel.onByte / 16) & 0x00FFFFF) | 0x0F000000); CGCORE_WRITE_REG( 0x30, ((pState->transfer.cancel.onByte / 16) & 0x00FFFFF) | 0x0F000000); CGCORE_WRITE_REG( 0x34, 0); // check if cancel point passed pResults->rc = CgxDriverIsReadCanceled(pState); if ((pControl->cancel.onByteCount == 0) || // Cancel snap req immediately (!OK(pResults->rc) && pState->flags.wait)) {// release a waiting thread, if any CGCoreReset(CGCORE_ENABLE_CORE); CgCpuDmaStop(CG_DRIVER_DMA_CHANNEL_READ); CgxDriverDataReadyInterruptHandler(pDriver, pState); } break; case CGX_IOCTL_ALLOC_BUFF: DBGMSG1("CGX_IOCTL_ALLOC_BUFF, pControl->alloc.length=%d", pControl->alloc.length); // pControl->alloc.length = 1 *1024 * 1024; // 1M pResults->rc = CgxDriverAllocInternalBuff(pDriver, pControl->alloc.length, (void**)&(pResults->buffer.bufferPhysAddr), pControl->alloc.processId); DBGMSG1("alloc p =0x%08X", pState->buffer.virtAddr); if (OK(pResults->rc)) { pResults->buffer.size = pControl->alloc.length; pResults->buffer.bufferAppVirtAddr = pState->buffer.virtAddr; } break; case CGX_IOCTL_FREE_BUFF: DBGMSG("CGX_IOCTL_FREE_BUFF"); pResults->rc = CgxDriverFreeInternalBuff(pDriver, pControl->alloc.processId); break; case CGX_IOCTL_READ_MEM: DBGMSG("CGX_IOCTL_READ_MEM"); pState->transfer.cancel.request = FALSE; DBGMSG1("read from 0x%08X", pControl->readReg.offset); pResults->rc = CgxCpuReadMemory(pControl->readReg.offset, 0, &pResults->readReg.value); break; case CGX_IOCTL_CPU_REVISION: pResults->rc = CgCpuRevision(pResults->cpuRevision.revisionCode); // TODO - fix CgCpuRevision so it reads from the right address break; case CGX_IOCTL_TCXO_ENABLE: DBGMSG("CGX_IOCTL_TCXO_ENABLE"); pResults->rc = CgxDriverTcxoControl(pControl->tcxoControl.enable); break; case CGX_IOCTL_RF_WRITE_CONTROL: DBGMSG("CGX_IOCTL_RF_WRITE_CONTROL"); pResults->rc = CgCpuRFControlWriteByte(pControl->writeReg.value); break; default: return ECgGeneralFailure; } return ECgOk; } TCgReturnCode CgxDriverPowerOn(void) { TCgReturnCode rc = ECgOk; gps_chip_power_on(); // Enable clock to the GPS device msleep(1); rc = CGCoreEnable(CGCORE_ENABLE_TCXO); return rc; } TCgReturnCode CgxDriverPowerOff(void) { TCgReturnCode rc = ECgOk; // Disable clock to the GPS device rc = CGCoreDisable(CGCORE_ENABLE_TCXO); gps_chip_power_off(); return rc; } TCgReturnCode CgxDriverTcxoControl(u32 aEnable) { TCgReturnCode rc = ECgOk; if(aEnable) CGCoreEnable(CGCORE_ENABLE_TCXO); else CGCoreDisable(CGCORE_ENABLE_TCXO); return rc; } TCgReturnCode CgCGCoreGpioSet(U32 aGpioPin, U32 aVal) { TCgReturnCode rc = ECgOk; U32 valToSet = 0; if (aGpioPin <= 0 || aGpioPin > 4) rc = ECgBadArgument; if (OK(rc)) rc = CGCORE_READ_REG( CGCORE_REG_OFFSET_GPO, &valToSet); REG_SET1(valToSet,aGpioPin,aVal ? 1 : 0); if (OK(rc)) rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_GPO, valToSet ); return rc; } /* TCgReturnCode CgxDriverRFPowerDown(void) { DBG_FUNC_NAME("CgxDriverRFPowerDown") TCgReturnCode rc = ECgOk; #if CG_DRIVER_CG_CORE_CONTROLS_RF_PD // Do nothing - Core controls RF power down pin #else #ifdef RF_POWER_UP_VAL rc = CgCpuGpioSet(CG_DRIVER_GPIO_RF_PD, RF_POWER_UP_VAL); #else rc = CgCpuGpioSet(CG_DRIVER_GPIO_RF_PD, 1); #endif #endif return rc; } TCgReturnCode CgxDriverRFPowerUp(void) { DBG_FUNC_NAME("CgxDriverRFPowerUp"); TCgReturnCode rc = ECgOk; #if CG_DRIVER_CG_CORE_CONTROLS_RF_PD // Do nothing - Core controls RF power down pin #else #ifdef RF_POWER_UP_VAL rc = CgCpuGpioSet(CG_DRIVER_GPIO_RF_PD, !RF_POWER_UP_VAL); #else rc = CgCpuGpioSet(CG_DRIVER_GPIO_RF_PD, 0); #endif #endif return rc; } */