/** * \brief Writes or reads the QSPI memory (0x80000000) to transmit or * receive data from Flash memory * \param pQspi Pointer to an Qspi instance. * \param ReadWrite Flag to indicate read/write QSPI memory access * * \return Returns 1 if At least one instruction end has been detected since * the last read of QSPI_SR.; otherwise returns 0. */ QspidStatus_t QSPI_ReadWriteMem(Qspid_t *pQspid, Access_t const ReadWrite) { QspidStatus_t Status = QSPI_UNKNOWN_ERROR; QspiInstFrame_t *const pFrame = pQspid->pQspiFrame; uint32_t *pQspiMem = (uint32_t *)(QSPIMEM_ADDR | pFrame->Addr); QspiBuffer_t pBuffer = pQspid->qspiBuffer; assert(((ReadWrite > CmdAccess) && (ReadWrite <= WriteAccess)) ? true : false); if (ReadWrite == WriteAccess) memcpy(pQspiMem, pBuffer.pDataTx , pBuffer.TxDataSize); else memcpy(pBuffer.pDataRx, pQspiMem, pBuffer.RxDataSize); memory_sync(); QSPI_EndTransfer(pQspid->pQspiHw); // End transmission after all data has been sent while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE)); // poll CR reg to know status if instruction has end Status = QSPI_SUCCESS; return Status; }
/** * \brief Send instruction over QSPI to read data * * \param pQspi Pointer to an Qspi instance. * \param KeepCfg To keep Instruction from value or resets to zero * * \return Returns 1 if At least one instruction end has been detected * since the last read of QSPI_SR.; otherwise returns 0. */ QspidStatus_t QSPI_ReadCommand(Qspid_t *pQspid, uint8_t const KeepCfg) { QspiInstFrame_t *const pFrame = pQspid->pQspiFrame; QspiMemCmd_t pCommand = pQspid->qspiCommand; QspiBuffer_t pBuffer = pQspid->qspiBuffer; uint32_t *pQspiBuffer = (uint32_t *)QSPIMEM_ADDR; QspidStatus_t Status = QSPI_UNKNOWN_ERROR; assert(pBuffer.pDataRx); QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF), (pCommand.Option & 0xFF)); QSPI_SetInstFrame(pQspid->pQspiHw, pFrame); QSPI_GetInstFrame(pQspid->pQspiHw); // to synchronize system bus accesses if (!KeepCfg) pFrame->InstFrame.val = 0; memcpy(pBuffer.pDataRx , pQspiBuffer, pBuffer.RxDataSize); memory_sync(); QSPI_EndTransfer(pQspid->pQspiHw); // End transmission after all data has been sent while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE)); // poll CR reg to know status if instruction has end return Status; }
/** * \brief Process successfully sent packets * \param pGmacd Pointer to GMAC Driver instance. */ static void GMACD_TxCompleteHandler(sGmacd *pGmacd, gmacQueList_t qId) { Gmac *pHw = pGmacd->pHw; sGmacTxDescriptor *pTxTd; fGmacdTransferCallback fTxCb; uint32_t tsr; /* Clear status */ tsr = GMAC_GetTxStatus(pHw); GMAC_ClearTxStatus(pHw, tsr); while (!GCIRC_EMPTY( pGmacd->queueList[qId].wTxHead, pGmacd->queueList[qId].wTxTail)) { pTxTd = &pGmacd->queueList[qId].pTxD[pGmacd->queueList[qId].wTxTail]; /* Make hw descriptor updates visible to CPU */ GMAC_CACHE_COHERENCE /* Exit if frame has not been sent yet: * On TX completion, the GMAC set the USED bit only into the * very first buffer descriptor of the sent frame. * Otherwise it updates this descriptor with status error bits. * This is the descriptor write back. */ if ((pTxTd->status.val & GMAC_TX_USED_BIT) == 0) break; /* Process all buffers of the current transmitted frame */ while ((pTxTd->status.val & GMAC_TX_LAST_BUFFER_BIT) == 0) { GCIRC_INC(pGmacd->queueList[qId].wTxTail, pGmacd->queueList[qId].wTxListSize); pTxTd = &pGmacd->queueList[qId].pTxD[pGmacd->queueList[qId].wTxTail]; memory_sync(); } /* Notify upper layer that a frame has been sent */ fTxCb = pGmacd->queueList[qId].fTxCbList[pGmacd->queueList[qId].wTxTail]; if (fTxCb) fTxCb(tsr); /* Go to next frame */ GCIRC_INC(pGmacd->queueList[qId].wTxTail, pGmacd->queueList[qId].wTxListSize); } /* If a wakeup has been scheduled, notify upper layer that it can send other packets, send will be successful. */ if (pGmacd->queueList[qId].fWakupCb && GCIRC_SPACE(pGmacd->queueList[qId].wTxHead, pGmacd->queueList[qId].wTxTail, pGmacd->queueList[qId].wTxListSize) >= pGmacd->queueList[qId].bWakeupThreshold) pGmacd->queueList[qId].fWakupCb(); }
/** * \brief SPI xDMA Rx callback * Invoked on SPi DMA reception done. * \param channel DMA channel. * \param pArg Pointer to callback argument - Pointer to Spid instance. */ static void QSPID_Spi_Cb(uint32_t channel, QspiDma_t *pArg) { Qspi *pQspiHw = pArg->Qspid.pQspiHw; if (channel != pArg->RxChNum) return; /* Release the semaphore */ ReleaseMutex(pArg->progress); QSPI_EndTransfer(pQspiHw); SCB_InvalidateDCache_by_Addr((uint32_t *)pArg->Qspid.qspiBuffer.pDataRx, pArg->Qspid.qspiBuffer.RxDataSize); memory_sync(); }
/** * \brief QSPI xDMA Tx callback * Invoked on QSPi DMA Write done. * \param channel DMA channel. * \param pArg Pointer to callback argument - Pointer to Spid instance. */ static void QSPID_qspiTx_Cb(uint32_t channel, QspiDma_t *pArg) { Qspi *pQspiHw = pArg->Qspid.pQspiHw; if (channel != pArg->TxChNum) return; /* Release the semaphore */ ReleaseMutex(pArg->progress); QSPI_EndTransfer(pQspiHw); while (!QSPI_GetStatus(pArg->Qspid.pQspiHw, IsEofInst)); memory_sync(); }
/** * \brief Start DMA sending/waiting data. */ static void _SscDma(volatile uint32_t *pReg, uint32_t dmaChannel, void *pBuffer, uint16_t wSize) { sXdmad *pDmad = &dmad; sXdmadCfg xdmadCfg; xdmadCfg.mbr_ubc = wSize; xdmadCfg.mbr_sa = (uint32_t) pBuffer; xdmadCfg.mbr_da = (uint32_t) pReg; xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_HALFWORD | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( ID_SSC, XDMAD_TRANSFER_TX)); xdmadCfg.mbr_bc = 0; xdmadCfg.mbr_ds = 0; xdmadCfg.mbr_sus = 0; xdmadCfg.mbr_dus = 0; memory_sync(); XDMAD_ConfigureTransfer(pDmad, dmaChannel, &xdmadCfg, 0, 0, ( XDMAC_CIE_BIE | XDMAC_CIE_DIE | XDMAC_CIE_FIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE)); SCB_CleanDCache_by_Addr((uint32_t *)pBuffer, wSize); XDMAD_StartTransfer(pDmad, dmaChannel); SSC_EnableTransmitter(SSC); }
/** * \brief Send an instruction over QSPI (oly a flash command no data) * * \param pQspi Pointer to an Qspi instance. * \param KeepCfg To keep Instruction fram value or restes to zero * * \return Returns 1 if At least one instruction end has been detected since * the last read of QSPI_SR.; otherwise * returns 0. */ QspidStatus_t QSPI_SendCommand(Qspid_t *pQspid, uint8_t const KeepCfg) { QspiInstFrame_t *const pFrame = pQspid->pQspiFrame; QspiMemCmd_t pCommand = pQspid->qspiCommand; QspidStatus_t Status = QSPI_UNKNOWN_ERROR; if (pFrame->InstFrame.bm.bAddrEn) QSPI_SetInstAddr(pQspid->pQspiHw, pFrame->Addr); QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF), ((pCommand.Option >> QSPI_ICR_OPT_Pos) & 0xFF)); QSPI_SetInstFrame(pQspid->pQspiHw, pFrame); memory_sync(); while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE)); // poll CR reg to know status if instruction has end if (!KeepCfg) pFrame->InstFrame.val = 0; return Status; }
/** * \brief usart-hw-handshaking Application entry point.. * * Configures USART in hardware handshaking mode and * Timer Counter 0 to generate an interrupt every second. Then, start the first * transfer on the USART and wait in an endless loop. * * \return Unused (ANSI-C compatibility). */ int main( void ) { char pbaud_time[8]; uint32_t BytesRead, BytesToRead, baudrate, timeout, TxBytesLeft; uint8_t AppBufferRollOver = 0; uint8_t *pTxBuff; /* Disable watchdog*/ WDT_Disable(WDT); printf("-- USART Hardware Handshaking Example %s --\n\r", SOFTPACK_VERSION); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME); /* Enable I and D cache */ SCB_EnableICache(); SCB_EnableDCache(); /* Configure USART pins*/ PIO_Configure(pins, PIO_LISTSIZE(pins)); /* Configure systick for 1 ms. */ TimeTick_Configure(); NVIC_SetPriority(XDMAC_IRQn , XDMA_NVIC_PRIO); printf("\n\rEnter required baudrate:"); gets(pbaud_time); baudrate = (atoi(pbaud_time)) ? (atoi(pbaud_time)): 921600; printf("\n\rEnter required timeout (in microsec):"); gets(pbaud_time); timeout = atoi(pbaud_time); if (timeout > 1000) { timeout /= 1000; timeout = ((timeout * baudrate) / 1000); } else { timeout = (timeout * baudrate) / 1000000; } timeout = (timeout) ? ((timeout > MAX_RX_TIMEOUT) ? MAX_RX_TIMEOUT : timeout) \ : MAX_RX_TIMEOUT; printf("\n\r"); /* Configure USART */ _ConfigureUsart(baudrate, timeout); printf("\n\r"); /*Enable Rx channel of USART */ USARTD_EnableRxChannels(&Usartd, &UsartRx); #ifdef FULL_DUPLEX /*Enable Tx channel of USART */ USARTD_EnableTxChannels(&Usartd, &UsartTx); #endif /* Start receiving data and start timer*/ USARTD_RcvData(&Usartd); /*Initialize Ring buffer */ pUsartBuffer = (RignBuffer_t *)malloc(sizeof(RignBuffer_t)); _initCircularBuffer(pUsartBuffer); pTxBuff = &FirstAppBuff[0]; TxBytesLeft = 0; #ifdef USE_MD5_CHECK md5_init(&pms); #endif //USE_MD5_CHECK #ifdef FULL_DUPLEX printf( "\n\r-I- USART is in Full Duplex mode \n\r"); #else printf( "\n\r-I- USART is in Half Duplex mode \n\r"); #endif printf( "\n\r-I- Please send a file to serial port (USART0) \n\r"); BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer while (1) { #ifdef USE_MD5_CHECK if (DBG_IsRxReady()) { ch = DBG_GetChar(); if (ch == 'm') { uint8_t i; md5_finish(&pms, md5); printf("\r\nmd5:"); for (i = 0; i < sizeof(md5);i++) printf("%.2x",md5[i]); printf("\r\n"); md5_init(&pms); TotalbytesReceived = 0; } } #endif /* Check Application buffer (100 KB)overflow */ if (((PingPongBufferFlag == 0) && (pTxBuff+BytesToRead) >= &FirstAppBuff[APP_BUFFER]) || (( PingPongBufferFlag == 1) && (pTxBuff+BytesToRead) >= &SecondAppBuff[APP_BUFFER])) { AppBufferRollOver = 1; // Roll over and start copying to the beginning of Application buffer to avoid errors if (PingPongBufferFlag) BytesToRead = (&SecondAppBuff[APP_BUFFER] - pTxBuff); else BytesToRead = (&FirstAppBuff[APP_BUFFER] - pTxBuff); memory_barrier(); } /* Read ring buffer */ BytesRead = RingBufferRead(pUsartBuffer, pTxBuff, BytesToRead); memory_sync(); TxBytesLeft += BytesRead; // number of bytes to send via USART Tx #ifdef USE_MD5_CHECK if (BytesRead > 0) md5_append(&pms,pTxBuff,BytesRead); #endif /* check if one of the application buffer is full and ready to send */ if (AppBufferRollOver && (TxBytesLeft == APP_BUFFER)) { AppBufferRollOver = 0; TxBytesLeft = 0; BytesRead = 0; BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer while (!UsartTx.dmaProgress); if (PingPongBufferFlag) { PingPongBufferFlag = 0; pTxBuff = &FirstAppBuff[0]; } else { PingPongBufferFlag = 1; pTxBuff = &SecondAppBuff[0]; } memory_sync(); #ifdef FULL_DUPLEX USARTD_SendData(&Usartd); #endif } /* otherwise keep storing in same application buffer from Rx DMA's ring buffer */ else { BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer pTxBuff += BytesRead; #ifdef FULL_DUPLEX /* Check for Tx timeout, if there is timeout then send the bytes left (less than 100 KB) in application buffer */ if ((GetDelayInTicks(TimeOutTimer, GetTicks()) == USART_TX_TIMEOUT) && TxBytesLeft) { // wait for any eventual USART Tx in progress while (!UsartTx.dmaProgress); FlushTxBuffer(TxBytesLeft); TimeOutTimer = GetTicks(); PingPongBufferFlag = 0; TxBytesLeft = 0; BytesRead = 0; BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer pTxBuff = &FirstAppBuff[0]; _UpdateTxConfig((uint32_t)&FirstAppBuff[0], APP_BUFFER); TRACE_INFO_WP(" TX Tiemout \n\r"); } #endif } } }
/** * \brief Ring buffer management * This function copies data from ring buffer to application buffer with a given length. * \param pBuff Usart Rx DMA ring buffer * \param pDestination Usart application buffer * \param Len Num of dat to copy from ring buffer * \return function returns number of bytes read from ringbuffer * */ static uint32_t RingBufferRead(RignBuffer_t *pBuff, uint8_t *pDestination, uint32_t Len) { uint32_t EndAddrs = ((uint32_t)pBuff->pBuffer + pBuff->BuffSize); uint32_t UnreadCount = 0; uint32_t EnableRTS = 0; uint32_t TotalLen = 0; uint32_t TailAddrs, BytesLeft; /* If timeout has occurred then re calculate the unread number of bytes */ if (dmaflush) { mutexTimeout = 0x7FF; BASE_USART->US_CR = US_CR_RTSEN; // disable transmission __disable_irq(); while (LockMutex(semaphore, mutexTimeout)); // lock mutex _UpdateCount(); /* If Circular buffer has still free space to fill */ if (pBuff->Count < MAX_FREE_BYTES) EnableRTS = US_CR_RTSDIS; dmaflush = 0; memory_sync(); ReleaseMutex(semaphore); BASE_USART->US_CR = EnableRTS; __enable_irq(); } /* If there are unread bytes in ringbuffer then copy them to application buffer */ if (pBuff->Count) { UnreadCount = __LDREXW(&pBuff->Count); // unread bytes count memory_barrier(); TotalLen = (Len > UnreadCount) ? UnreadCount : Len; // if read length surpasses the ring buffer boundary, then loop over if ((pBuff->pTail + TotalLen) >= EndAddrs) { BytesLeft = (EndAddrs - pBuff->pTail); memcpy( pDestination , (uint32_t *)pBuff->pTail, BytesLeft ); memcpy( (pDestination +(EndAddrs - pBuff->pTail)), (uint32_t *)(pBuff->pBuffer), TotalLen - BytesLeft); TailAddrs = ( (uint32_t)pBuff->pBuffer + (TotalLen - BytesLeft)); } else { memcpy( pDestination , (uint32_t *)pBuff->pTail, TotalLen); TailAddrs = pBuff->pTail + TotalLen; } /* In this part function enable the RTS signal to stop all reception disable irq to enter in critical part gets a lock on semaphore updates Tail pointer and count of ring buffer check if RTS need to be disable to accept the data from host frees the semaphore and enable irq*/ BASE_USART->US_CR = US_CR_RTSEN; // disable transmission __disable_irq(); mutexTimeout = 0x7FF; while (LockMutex(semaphore, mutexTimeout)); // lock mutex pBuff->pTail = TailAddrs; pBuff->Count -=TotalLen; // update count of ring buffer TotalbytesReceived +=TotalLen; memory_sync(); #ifdef FULL_DUPLEX TimeOutTimer = GetTicks(); #endif /* If Circular buffer is read completely */ if (pUsartBuffer->Count < MAX_FREE_BYTES) EnableRTS = US_CR_RTSDIS; ReleaseMutex(semaphore); BASE_USART->US_CR = EnableRTS; __enable_irq(); printf("\r Total bytes received 0x%x (%u)", \ (unsigned)TotalbytesReceived, (unsigned)TotalbytesReceived); return TotalLen; // return the number of bytes } else return 0; }
/** * \brief Set up a memory region. */ void _SetupMemoryRegion( void ) { uint32_t dwRegionBaseAddr; uint32_t dwRegionAttr; memory_barrier(); /*************************************************** ITCM memory region --- Normal START_Addr:- 0x00000000UL END_Addr:- 0x00400000UL ****************************************************/ dwRegionBaseAddr = ITCM_START_ADDRESS | MPU_REGION_VALID | MPU_DEFAULT_ITCM_REGION; // 1 dwRegionAttr = MPU_AP_PRIVILEGED_READ_WRITE | MPU_CalMPURegionSize(ITCM_END_ADDRESS - ITCM_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** Internal flash memory region --- Normal read-only (update to Strongly ordered in write accesses) START_Addr:- 0x00400000UL END_Addr:- 0x00600000UL ******************************************************/ dwRegionBaseAddr = IFLASH_START_ADDRESS | MPU_REGION_VALID | MPU_DEFAULT_IFLASH_REGION; //2 dwRegionAttr = MPU_AP_READONLY | INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) | MPU_CalMPURegionSize(IFLASH_END_ADDRESS - IFLASH_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** DTCM memory region --- Normal START_Addr:- 0x20000000L END_Addr:- 0x20400000UL ******************************************************/ /* DTCM memory region */ dwRegionBaseAddr = DTCM_START_ADDRESS | MPU_REGION_VALID | MPU_DEFAULT_DTCM_REGION; //3 dwRegionAttr = MPU_AP_PRIVILEGED_READ_WRITE | MPU_CalMPURegionSize(DTCM_END_ADDRESS - DTCM_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** SRAM Cacheable memory region --- Normal START_Addr:- 0x20400000UL END_Addr:- 0x2043FFFFUL ******************************************************/ /* SRAM memory region */ dwRegionBaseAddr = SRAM_FIRST_START_ADDRESS | MPU_REGION_VALID | MPU_DEFAULT_SRAM_REGION_1; //4 dwRegionAttr = MPU_AP_FULL_ACCESS | INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) | MPU_CalMPURegionSize(SRAM_FIRST_END_ADDRESS - SRAM_FIRST_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** Internal SRAM second partition memory region --- Normal START_Addr:- 0x20440000UL END_Addr:- 0x2045FFFFUL ******************************************************/ /* SRAM memory region */ dwRegionBaseAddr = SRAM_SECOND_START_ADDRESS | MPU_REGION_VALID | MPU_DEFAULT_SRAM_REGION_2; //5 dwRegionAttr = MPU_AP_FULL_ACCESS | INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) | MPU_CalMPURegionSize(SRAM_SECOND_END_ADDRESS - SRAM_SECOND_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** Peripheral memory region --- DEVICE Shareable START_Addr:- 0x40000000UL END_Addr:- 0x5FFFFFFFUL ******************************************************/ dwRegionBaseAddr = PERIPHERALS_START_ADDRESS | MPU_REGION_VALID | MPU_PERIPHERALS_REGION; //6 dwRegionAttr = MPU_AP_FULL_ACCESS | MPU_REGION_EXECUTE_NEVER | SHAREABLE_DEVICE_TYPE | MPU_CalMPURegionSize(PERIPHERALS_END_ADDRESS - PERIPHERALS_START_ADDRESS) |MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** External EBI memory memory region --- Strongly Ordered START_Addr:- 0x60000000UL END_Addr:- 0x6FFFFFFFUL ******************************************************/ dwRegionBaseAddr = EXT_EBI_START_ADDRESS | MPU_REGION_VALID | MPU_EXT_EBI_REGION; dwRegionAttr = MPU_AP_FULL_ACCESS | /* External memory Must be defined with 'Device' or 'Strongly Ordered' attribute for write accesses (AXI) */ STRONGLY_ORDERED_SHAREABLE_TYPE | MPU_CalMPURegionSize(EXT_EBI_END_ADDRESS - EXT_EBI_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** SDRAM Cacheable memory region --- Normal START_Addr:- 0x70000000UL END_Addr:- 0x7FFFFFFFUL ******************************************************/ dwRegionBaseAddr = SDRAM_START_ADDRESS | MPU_REGION_VALID | MPU_DEFAULT_SDRAM_REGION; //7 dwRegionAttr = MPU_AP_FULL_ACCESS | INNER_NORMAL_WB_RWA_TYPE( SHAREABLE ) | MPU_CalMPURegionSize(SDRAM_END_ADDRESS - SDRAM_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** QSPI memory region --- Strongly ordered START_Addr:- 0x80000000UL END_Addr:- 0x9FFFFFFFUL ******************************************************/ dwRegionBaseAddr = QSPI_START_ADDRESS | MPU_REGION_VALID | MPU_QSPIMEM_REGION; //8 dwRegionAttr = MPU_AP_FULL_ACCESS | STRONGLY_ORDERED_SHAREABLE_TYPE | MPU_CalMPURegionSize(QSPI_END_ADDRESS - QSPI_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** USB RAM Memory region --- Device START_Addr:- 0xA0100000UL END_Addr:- 0xA01FFFFFUL ******************************************************/ dwRegionBaseAddr = USBHSRAM_START_ADDRESS | MPU_REGION_VALID | MPU_USBHSRAM_REGION; //9 dwRegionAttr = MPU_AP_FULL_ACCESS | MPU_REGION_EXECUTE_NEVER | SHAREABLE_DEVICE_TYPE | MPU_CalMPURegionSize(USBHSRAM_END_ADDRESS - USBHSRAM_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /* Enable the memory management fault , Bus Fault, Usage Fault exception */ SCB->SHCSR |= (SCB_SHCSR_MEMFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_USGFAULTENA_Msk); /* Enable the MPU region */ MPU_Enable( MPU_ENABLE | MPU_PRIVDEFENA); memory_sync(); }