DRESULT disk_write ( BYTE drv, /* Physical drive nmuber (0) */ const BYTE *buff, /* Pointer to the data to be written */ DWORD sector, /* Start sector number (LBA) */ BYTE count /* Sector count (1..128) */ ) { CyU3PReturnStatus_t status; CyU3PDmaBuffer_t BufOUT_t; uint32_t evStat; /* No storage device found. */ if ((Stat[drv] == STA_NOINIT) || (Stat[drv] == STA_NODISK)) return RES_NOTRDY; /* FX3S cannot handle DMA buffers larger that 65535 bytes. */ if (count < 1 || count > 127) return RES_PARERR; /* Check whether the volume is write protected. */ if (Stat[drv] == STA_PROTECT) return RES_WRPRT; BufOUT_t.buffer = (uint8_t *)buff; BufOUT_t.count = (uint16_t)count * 512; BufOUT_t.size = (uint16_t)count * 512; BufOUT_t.status = 0; status = CyU3PSibReadWriteRequest (CyFalse, (uint8_t) drv, 0, (uint16_t)count, (uint32_t)sector, (uint8_t)CY_U3P_SIB_SOCKET_0); if (status != CY_U3P_SUCCESS) { /* Abort the DMA Channel */ CyU3PDmaChannelReset (&glChHandleStorOut); return RES_ERROR; } status = CyU3PDmaChannelSetupSendBuffer (&glChHandleStorOut, &BufOUT_t); if (status == CY_U3P_SUCCESS) { status = CyU3PEventGet (&glStorDriverEvent, CY_FX_FATFS_SIB_DONE_EVENT, CYU3P_EVENT_OR_CLEAR, &evStat, CYU3P_WAIT_FOREVER); if (status == CY_U3P_SUCCESS) status = CyU3PDmaChannelWaitForCompletion (&glChHandleStorOut, CYU3P_WAIT_FOREVER); } if (status != CY_U3P_SUCCESS) { CyU3PSibAbortRequest ((uint8_t)drv); CyU3PDmaChannelReset (&glChHandleStorOut); } return status ? RES_ERROR : RES_OK; }
DRESULT disk_read ( BYTE drv, /* Physical drive nmuber (0) */ BYTE *buff, /* Pointer to the data buffer to store read data */ DWORD sector, /* Start sector number (LBA) */ BYTE count /* Sector count (1..128) */ ) { CyU3PReturnStatus_t status; CyU3PDmaBuffer_t BufIN_t; uint32_t evStat; /* No storage device found. */ if ((Stat[drv] == STA_NOINIT) || (Stat[drv] == STA_NODISK)) return RES_NOTRDY; /* FX3S cannot handle DMA buffers larger that 65535 bytes. */ if (count < 1 || count > 127) return RES_PARERR; BufIN_t.buffer = (uint8_t *) buff; BufIN_t.count = 0; BufIN_t.size = 512 * count; BufIN_t.status = 0; status = CyU3PDmaChannelSetupRecvBuffer ( &glChHandleStorIn, &BufIN_t); if (status == CY_U3P_SUCCESS) { status = CyU3PSibReadWriteRequest (CyTrue, (uint8_t) drv, 0, (uint16_t)count, (uint32_t)sector, (uint8_t) CY_U3P_SIB_SOCKET_1); if (status != CY_U3P_SUCCESS) { /* Abort the DMA Channel */ CyU3PDmaChannelReset (&glChHandleStorIn); return RES_ERROR; } } /* Wait until we get the SIB transfer done event. */ status = CyU3PEventGet (&glStorDriverEvent, CY_FX_FATFS_SIB_DONE_EVENT, CYU3P_EVENT_OR_CLEAR, &evStat, CYU3P_WAIT_FOREVER); if (status == CY_U3P_SUCCESS) status = CyU3PDmaChannelWaitForRecvBuffer (&glChHandleStorIn, &BufIN_t, CYU3P_WAIT_FOREVER); if (status != CY_U3P_SUCCESS) { CyU3PSibAbortRequest ((uint8_t)drv); CyU3PDmaChannelReset (&glChHandleStorIn); } return status ? RES_ERROR : RES_OK; }
void NuandFpgaConfigStop(void) { CyU3PEpConfig_t epCfg; CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS; /* Abort and clear the channel */ CyU3PDmaChannelReset(&glChHandlebladeRFUtoP); /* Flush the endpoint memory */ CyU3PUsbFlushEp(BLADE_FPGA_EP_PRODUCER); /* Destroy the channel */ CyU3PDmaChannelDestroy(&glChHandlebladeRFUtoP); /* Disable endpoints. */ CyU3PMemSet((uint8_t *)&epCfg, 0, sizeof (epCfg)); epCfg.enable = CyFalse; /* Producer endpoint configuration. */ apiRetStatus = CyU3PSetEpConfig(BLADE_FPGA_EP_PRODUCER, &epCfg); if (apiRetStatus != CY_U3P_SUCCESS) { LOG_ERROR(apiRetStatus); CyFxAppErrorHandler (apiRetStatus); } apiRetStatus = NuandConfigureGpif(GPIF_CONFIG_DISABLED); if (apiRetStatus != CY_U3P_SUCCESS) { LOG_ERROR(apiRetStatus); CyFxAppErrorHandler(apiRetStatus); } NuandAllowSuspend(CyTrue); glAppMode = MODE_NO_CONFIG; CyU3PGpioSetValue(GPIO_SYS_RST, CyTrue); }
CyU3PReturnStatus_t CyFxMscErrorRecovery ( void) { CyU3PReturnStatus_t status = CY_U3P_SUCCESS; /* Abort and reset the IN endpoint. */ if (glMscInEp != 0) { CyU3PDmaChannelReset (&glMscInCh); CyU3PUsbHostEpAbort (glMscInEp); status = CyFxSendSetupRqt (0x02, CY_U3P_USB_SC_CLEAR_FEATURE, 0, glMscInEp, 0, glEp0Buffer); if (status == CY_U3P_SUCCESS) { status = CyU3PUsbHostEpReset (glMscInEp); } } /* Abort and reset the OUT endpoint. */ if ((status == CY_U3P_SUCCESS) && (glMscOutEp != 0)) { CyU3PDmaChannelReset (&glMscOutCh); CyU3PUsbHostEpAbort (glMscOutEp); status = CyFxSendSetupRqt (0x02, CY_U3P_USB_SC_CLEAR_FEATURE, 0, glMscOutEp, 0, glEp0Buffer); if (status == CY_U3P_SUCCESS) { status = CyU3PUsbHostEpReset (glMscOutEp); } } return status; }
void CyFxGpifAppRqtHandler ( void) { CyU3PReturnStatus_t status; CyU3PMbox rspMbox; uint8_t rqtCode; uint8_t params[7]; /* Break the request data into bytes. */ rqtCode = CY_U3P_DWORD_GET_BYTE3 (fxAppMbox.w0); /* The request code is the MSB of w0. */ params[0] = CY_U3P_DWORD_GET_BYTE2 (fxAppMbox.w0); params[1] = CY_U3P_DWORD_GET_BYTE1 (fxAppMbox.w0); params[2] = CY_U3P_DWORD_GET_BYTE0 (fxAppMbox.w0); params[3] = CY_U3P_DWORD_GET_BYTE3 (fxAppMbox.w1); params[4] = CY_U3P_DWORD_GET_BYTE2 (fxAppMbox.w1); params[5] = CY_U3P_DWORD_GET_BYTE1 (fxAppMbox.w1); params[6] = CY_U3P_DWORD_GET_BYTE0 (fxAppMbox.w1); switch (rqtCode) { case CYFXSTORRQT_INIT: { /* SIB start request. No parameters are used for this request. */ status = CyU3PSibStart (); /* SIB start has succeeded. We can create the DMA channels for data transfer at this stage. */ if (status == CY_U3P_SUCCESS) { status = CyFxGpifAppCreateDmaChannels (); /* Register a callback for SIB events. */ CyU3PSibRegisterCbk (CyFxGpifAppSibCallback); } rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | status; rspMbox.w1 = 0; CyU3PMboxWrite (&rspMbox); } break; case CYFXSTORRQT_DEINIT: { /* SIB start request. No parameters are used for this request. */ CyU3PSibStop (); /* SIB stop is complete. We can tear down the DMA channels at this stage. */ CyFxGpifAppDestroyDmaChannels (); rspMbox.w0 = (CYFXSTORRESP_STATUS << 24); rspMbox.w1 = 0; CyU3PMboxWrite (&rspMbox); } break; case CYFXSTORRQT_PORTCFG: { CyU3PSibIntfParams_t intfCfg; /* Populate the structure with data from the mailbox request. */ intfCfg.rstActHigh = ((params[1] & 0x01) == 0x01) ? 1 : 0; intfCfg.writeProtEnable = ((params[1] & 0x02) == 0x02) ? 1 : 0; intfCfg.lowVoltage = ((params[1] & 0x04) == 0x04) ? 1 : 0; intfCfg.useDdr = ((params[1] & 0x08) == 0x08) ? 1 : 0; intfCfg.resetGpio = params[2]; intfCfg.cardDetType = params[3]; intfCfg.voltageSwGpio = params[4]; intfCfg.lvGpioState = CyFalse; intfCfg.maxFreq = CY_U3P_SIB_FREQ_104MHZ; /* No S port clock limitation. */ intfCfg.cardInitDelay = 0; /* No SD/MMC initialization delay. */ status = CyU3PSibSetIntfParams (params[0], &intfCfg); rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | status; rspMbox.w1 = 0; CyU3PMboxWrite (&rspMbox); } break; case CYFXSTORRQT_QUERYDEV: { CyU3PSibDevInfo_t devInfo; status = CyU3PSibQueryDevice (params[0], &devInfo); if (status == CY_U3P_SUCCESS) { /* Only some of the device info fields are being returned here, so as to restrict the response to 8 bytes. This can be expanded by breaking up the response into multiple messages. */ rspMbox.w0 = CY_U3P_MAKEDWORD (CYFXSTORRESP_DEVDATA, (uint8_t)devInfo.cardType, (uint8_t)devInfo.numUnits, (uint8_t)devInfo.writeable); rspMbox.w1 = (uint32_t)devInfo.blkLen; fxAppDevBlkSize = devInfo.blkLen; } else { rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | status; rspMbox.w1 = 0; } CyU3PMboxWrite (&rspMbox); } break; case CYFXSTORRQT_QUERYUNIT: { CyU3PSibLunInfo_t unitInfo; status = CyU3PSibQueryUnit (params[0], params[1], &unitInfo); if (status == CY_U3P_SUCCESS) { /* Only some of the device info fields are being returned here, so as to restrict the response to 8 bytes. This can be expanded by breaking up the response into multiple messages. */ rspMbox.w0 = CY_U3P_MAKEDWORD (CYFXSTORRESP_UNITDATA, (uint8_t)unitInfo.valid, (uint8_t)unitInfo.location, (uint8_t)unitInfo.type); rspMbox.w1 = unitInfo.numBlocks; } else { rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | status; rspMbox.w1 = 0; } CyU3PMboxWrite (&rspMbox); } break; case CYFXSTORRQT_READ: { uint32_t flag; status = CyU3PDmaChannelSetXfer (&fxAppReadChannel, params[3] * fxAppDevBlkSize); if (status == CY_U3P_SUCCESS) { status = CyU3PSibReadWriteRequest (CyTrue, params[0], params[1], params[2], fxAppMbox.w1, CYFXSTORAPP_SIB_RDSOCK); if (status == CY_U3P_SUCCESS) { status = CyU3PEventGet (&fxAppEvent, CYFXAPP_SIB_DONE_EVENT, CYU3P_EVENT_OR_CLEAR, &flag, CYFXSTORAPP_XFER_TIMEOUT); if (status == CY_U3P_SUCCESS) { if (fxAppXferStatus == CY_U3P_SUCCESS) { status = CyU3PDmaChannelWaitForCompletion (&fxAppReadChannel, CYFXSTORAPP_XFER_TIMEOUT); } else status = fxAppXferStatus; } if (status != CY_U3P_SUCCESS) { CyU3PSibAbortRequest (params[0]); CyU3PDmaChannelReset (&fxAppReadChannel); } } } rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | status; rspMbox.w1 = 0; CyU3PMboxWrite (&rspMbox); } break; case CYFXSTORRQT_WRITE: { uint32_t flag; status = CyU3PDmaChannelSetXfer (&fxAppWriteChannel, params[3] * fxAppDevBlkSize); if (status == CY_U3P_SUCCESS) { status = CyU3PSibReadWriteRequest (CyFalse, params[0], params[1], params[2], fxAppMbox.w1, CYFXSTORAPP_SIB_WRSOCK); if (status == CY_U3P_SUCCESS) { status = CyU3PEventGet (&fxAppEvent, CYFXAPP_SIB_DONE_EVENT, CYU3P_EVENT_OR_CLEAR, &flag, CYFXSTORAPP_XFER_TIMEOUT); if (status == CY_U3P_SUCCESS) { if (fxAppXferStatus == CY_U3P_SUCCESS) { status = CyU3PDmaChannelWaitForCompletion (&fxAppWriteChannel, CYFXSTORAPP_XFER_TIMEOUT); } else status = fxAppXferStatus; } if (status != CY_U3P_SUCCESS) { CyU3PSibAbortRequest (params[0]); CyU3PDmaChannelReset (&fxAppWriteChannel); } } } rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | status; rspMbox.w1 = 0; CyU3PMboxWrite (&rspMbox); } break; case CYFXSTORRQT_ECHO: { rspMbox.w0 = (CYFXSTORRESP_ECHO << 24) | (fxAppMbox.w0 & 0xFFFFFF); rspMbox.w1 = fxAppMbox.w1; CyU3PMboxWrite (&rspMbox); } break; default: { /* Unsupported command. */ rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | CY_U3P_ERROR_CMD_NOT_SUPPORTED; rspMbox.w1 = 0; CyU3PMboxWrite (&rspMbox); } break; } }
CyBool_t NuandLoadFromFlash(int fpga_len) { uint8_t *ptr; int nleft; CyBool_t retval = CyFalse; CyU3PDmaBuffer_t dbuf; uint32_t sector_idx = 1025; uint32_t prodCnt, consCnt; int32_t i; CyU3PDmaState_t state; CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS; NuandFpgaConfigStart(); ptr = CyU3PDmaBufferAlloc(4096); apiRetStatus = CyFxSpiInit(0x100); CyFxSpiFastRead(CyTrue); apiRetStatus = CyU3PSpiSetClock(30000000); if (FpgaBeginProgram() != CY_U3P_SUCCESS) { goto out; } nleft = fpga_len; while(nleft) { apiRetStatus = CyU3PDmaChannelGetStatus(&glChHandlebladeRFUtoP, &state, &prodCnt, &consCnt); if (apiRetStatus) break; CyU3PDmaChannelAbort(&glChHandlebladeRFUtoP); apiRetStatus = CyU3PDmaChannelGetStatus(&glChHandlebladeRFUtoP, &state, &prodCnt, &consCnt); if (apiRetStatus) break; CyU3PDmaChannelReset(&glChHandlebladeRFUtoP); apiRetStatus = CyU3PDmaChannelGetStatus(&glChHandlebladeRFUtoP, &state, &prodCnt, &consCnt); if (apiRetStatus) break; if (CyFxSpiTransfer(sector_idx++, 0x100, ptr, CyTrue) != CY_U3P_SUCCESS) break; uint8_t *end_in_b = &( ((uint8_t *)ptr)[255]); uint16_t *end_in_w = &( ((uint16_t *)ptr)[255]); /* Flip the bits in such a way that the FPGA can be programmed * This mapping can be determined by looking at the schematic */ for (i = 255; i >= 0; i--) *end_in_w-- = glFlipLut[*end_in_b--]; dbuf.buffer = ptr; dbuf.count = ((nleft > 256) ? 256 : (nleft + 2)) * 2; dbuf.size = 4096; dbuf.status = 0; apiRetStatus = CyU3PDmaChannelSetupSendBuffer(&glChHandlebladeRFUtoP, &dbuf); if (apiRetStatus) break; apiRetStatus = CyU3PDmaChannelGetStatus(&glChHandlebladeRFUtoP, &state, &prodCnt, &consCnt); if (apiRetStatus) break; apiRetStatus = CyU3PDmaChannelWaitForCompletion(&glChHandlebladeRFUtoP, 100); if (apiRetStatus) break; apiRetStatus = CyU3PDmaChannelGetStatus(&glChHandlebladeRFUtoP, &state, &prodCnt, &consCnt); if (apiRetStatus) break; if (nleft > 256) { nleft -= 256; } else { retval = CyTrue; nleft = 0; break; } } out: CyU3PDmaBufferFree(ptr); CyU3PSpiDeInit(); CyFxSpiFastRead(CyFalse); NuandFpgaConfigStop(); return retval; }