ADuCM4x50 Device Drivers API Reference Manual  Release 4.0.0.0
adi_flash.c
1 
56 /*======== I N C L U D E ========*/
57 
59 #include <adi_processor.h>
60 #include <assert.h>
61 #include <string.h> /* for "memset" */
64 #include <drivers/flash/adi_flash.h>
65 
66 /*============= M I S R A =============*/
67 
68 #ifdef __ICCARM__
69 /*
70 * IAR MISRA C 2004 error suppressions.
71 *
72 * Pm123 (rule 8.5): there shall be no definition of objects or functions in a header file
73 * This isn't a header as such.
74 *
75 * Pm073 (rule 14.7): a function should have a single point of exit
76 * Pm143 (rule 14.7): a function should have a single point of exit at the end of the function
77 * Multiple returns are used for error handling.
78 *
79 * Pm050 (rule 14.2): a null statement shall only occur on a line by itself
80 * Needed for null expansion of ADI_INSTALL_HANDLER and others.
81 *
82 * Pm088 (rule 17.4): pointer arithmetic should not be used.
83 * Relying on pointer arithmetic for buffer handling.
84 *
85 * Pm140 (rule 11.3): a cast should not be performed between a pointer type and an integral type
86 * Required for MMR accesses, determining pointer alignment, and a callback argument.
87 *
88 * Pm026 (rule 12.4): the right hand operand of an && or || operator shall not contain side effects
89 * Side effects being mis-reported due to added volatile storage class.
90 */
91 #pragma diag_suppress=Pm123,Pm073,Pm143,Pm050,Pm088,Pm140,Pm026
92 #endif /* __ICCARM__ */
93 
94 /* pull in internal data structures */
95 #include "adi_flash_data.c"
96 
97 /*======== D E F I N E S ========*/
98 
101 #ifdef ADI_DEBUG
102 #define ASSERT(X) assert(X)
103 #else
104 #define ASSERT(X)
105 #endif
106 
107 /* internal utility macros */
108 #define CLR_BITS(REG, BITS) ((REG) &= ~(BITS))
109 #define SET_BITS(REG, BITS) ((REG) |= (BITS))
110 
111 #ifdef ADI_DEBUG
112 /* Validate Device Handle */
113 static bool IsDeviceHandle (ADI_FEE_HANDLE const hDevice);
114 static bool IsDeviceHandle (ADI_FEE_HANDLE const hDevice)
115 {
116  if ( (fee_device_info[0].hDevice == (hDevice)) && ((hDevice)->pDevInfo->hDevice != NULL) ) {
117  return true;
118  } else {
119  return false;
120  }
121 }
122 #endif
123 
124 /* Wait for specified flash status to be clear */
125 static void BusyWait (ADI_FEE_HANDLE const hDevice, uint32_t const status);
126 static void BusyWait (ADI_FEE_HANDLE const hDevice, uint32_t const status)
127 {
128  while ((hDevice->pDev->STAT & status) != 0u) {}
129 }
130 
131 /* Internal DMA Callback for receiving DMA faults from common DMA error handler */
132 static void dmaCallback(void *pCBParam, uint32_t Event, void *pArg);
133 static void dmaCallback(void *pCBParam, uint32_t Event, void *pArg) {
134 
135  /* recover the device handle */
136  ADI_FEE_HANDLE hDevice = (ADI_FEE_HANDLE)pCBParam;
137 
138  /* save the DMA error */
139  switch (Event) {
141  hDevice->dmaError = ADI_FEE_ERR_DMA_BUS_FAULT;
142  break;
144  hDevice->dmaError = ADI_FEE_ERR_DMA_INVALID_DESCR;
145  break;
146  default:
147  hDevice->dmaError = ADI_FEE_ERR_DMA_UNKNOWN_ERROR;
148  break;
149  }
150 
151  /* transfer is toast... post and callback any waiters */
152 
153  SEM_POST(hDevice);
154 
155  if (0u != hDevice->pfCallback) {
156  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)hDevice->dmaError, (void*)NULL);
157  }
158 }
159 
163 /*======== C O D E ========*/
164 /*
165  * API Implementation
166  */
167 
168 
199 ADI_FEE_RESULT adi_fee_Open (uint32_t const nDeviceNum, void* const pMemory, uint32_t const nMemorySize, ADI_FEE_HANDLE* const phDevice)
200 {
201  ADI_FEE_HANDLE hDevice = NULL; /* initially */
202 
203 #ifdef ADI_DEBUG
204  if (nDeviceNum >= ADI_FEE_NUM_INSTANCES) {
206  }
207 
208  /* verify device is not already open */
209  if (fee_device_info[nDeviceNum].hDevice != NULL) {
211  }
212 
213  if ((pMemory == NULL) || (phDevice == NULL)) {
215  }
216 
217  if (nMemorySize < ADI_FEE_MEMORY_SIZE) {
219  }
220 
221  assert (ADI_FEE_MEMORY_SIZE == sizeof(ADI_FEE_DEV_DATA_TYPE));
222 #endif
223 
224  /* store a bad handle in case of failure */
225  *phDevice = NULL;
226 
227  /* Link user memory (handle) into ADI_FEE_DEVICE_INFO data structure.
228  *
229  * ADI_FEE_DEVICE_INFO <==> ADI_FEE_HANDLE
230  */
231  fee_device_info[nDeviceNum].hDevice = (ADI_FEE_DEV_DATA_TYPE *)pMemory;
232 
233  /* Clear the ADI_FEE_HANDLE memory. This also sets all bool
234  * structure members to false so we do not need to waste cycles
235  * setting these explicitly (e.g. hDevice->bUseDma = false)
236  */
237  memset(pMemory, 0, nMemorySize);
238 
239  /* initialize local device handle and link up device info for this device instance */
240  hDevice = (ADI_FEE_HANDLE)pMemory;
241  hDevice->pDevInfo = &fee_device_info[nDeviceNum];
242 
243  /* Although the ADI_FEE_DEVICE_INFO struct has the physical device pointer
244  * for this instance, copying it to the ADI_FEE_HANDLE struct (in user memory)
245  * will minimize the runtime footprint and cycle count when accessing the FEE
246  * registers.
247  */
248  hDevice->pDev = fee_device_info[nDeviceNum].pDev;
249 
250  /* store a pointer to user's static configuration settings for this device instance */
251  hDevice->pDevInfo->pConfig = (ADI_FEE_CONFIG*)&gConfigInfo[nDeviceNum];
252 
253  /* create the semaphore */
254  SEM_CREATE(hDevice, "fee_sem", ADI_FEE_ERR_SEMAPHORE_FAILED);
255 
256  /* grant keyed access */
257  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
258 
259  /* apply the static initializers */
260  hDevice->pDev->IEN = hDevice->pDevInfo->pConfig->eccIrqEnables;
261  hDevice->pDev->TIME_PARAM0 = hDevice->pDevInfo->pConfig->param0;
262  hDevice->pDev->TIME_PARAM1 = hDevice->pDevInfo->pConfig->param1;
263  hDevice->pDev->ABORT_EN_LO = hDevice->pDevInfo->pConfig->abortEnableLo;
264  hDevice->pDev->ABORT_EN_HI = hDevice->pDevInfo->pConfig->abortEnableHi;
265  hDevice->pDev->ECC_CFG = hDevice->pDevInfo->pConfig->eccConfig;
266 
267  /* clear auto-increment and dma enable bits */
268  CLR_BITS (hDevice->pDev->UCFG, (BITM_FLCC_UCFG_AUTOINCEN | BITM_FLCC_UCFG_KHDMAEN));
269 
270  /* close keyed access */
271  hDevice->pDev->KEY = 0u;
272 
273  /* store device handle into user handle */
274  *phDevice = (ADI_FEE_HANDLE)hDevice;
275 
276  /* initialize DMA service */
277  adi_dma_Init();
278 
279  if (ADI_DMA_SUCCESS != adi_dma_RegisterCallback(hDevice->pDevInfo->dmaChanNum, dmaCallback, (void*)hDevice)) {
280  /* uninitialize flash driver and fail */
281  adi_fee_Close(hDevice);
283  }
284 
285  /* NVIC enables */
286  NVIC_EnableIRQ(hDevice->pDevInfo->pioIrqNum);
287  NVIC_EnableIRQ(hDevice->pDevInfo->dmaIrqNum);
288 
289  /* return success */
290  return ADI_FEE_SUCCESS;
291 }
292 
293 
312 {
313  uint32_t dev;
314 
315 #ifdef ADI_DEBUG
316  if (true != IsDeviceHandle(hDevice)) {
318  }
319 #endif
320 
321  /* Destroy the semaphore */
322  SEM_DELETE(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
323 
324  /* Remove the device handle from the list of possible device instances */
325  for (dev = 0u; dev < ADI_FEE_NUM_INSTANCES; dev++)
326  {
327  if (fee_device_info[dev].hDevice == hDevice)
328  {
329  fee_device_info[dev].hDevice = NULL;
330  break;
331  }
332  }
333 
334  /* NVIC disables */
335  NVIC_DisableIRQ(hDevice->pDevInfo->pioIrqNum);
336  NVIC_DisableIRQ(hDevice->pDevInfo->dmaIrqNum);
337 
338  return ADI_FEE_SUCCESS;
339 }
340 
341 #if defined (__ADUCM4x50__)
342 
352 ADI_FEE_RESULT adi_fee_ConfigureWaitStates (ADI_FEE_HANDLE const hDevice, uint8_t numWaitStates)
353 {
354 #ifdef ADI_DEBUG
355  if (true != IsDeviceHandle(hDevice)) {
357  }
358 #endif
359  /* Flash key protect */
360  *pREG_FLCC0_KEY = ENUM_FLCC_KEY_USERKEY;
361 
362  /* Change flash wait state from 0 to 1. Necessary if system clock is greater than 26 MHz */
363  *pREG_FLCC0_TIME_PARAM1 |= ((((uint32_t)numWaitStates) << BITP_FLCC_TIME_PARAM1_WAITSTATES) & BITM_FLCC_TIME_PARAM1_WAITSTATES);
364 
365  /* Wait until wait states are changed */
366  while (((*pREG_FLCC0_TIME_PARAM1 & BITM_FLCC_TIME_PARAM1_CURWAITSTATES) != (1u << BITP_FLCC_TIME_PARAM1_CURWAITSTATES))){}
367 
368  return ADI_FEE_SUCCESS;
369 }
370 #endif
371 
407 ADI_FEE_RESULT adi_fee_RegisterCallback (ADI_FEE_HANDLE const hDevice, ADI_CALLBACK const pfCallback, void* const pCBParam)
408 {
409 #ifdef ADI_DEBUG
410  if (true != IsDeviceHandle(hDevice)) {
412  }
413 
414  /* reject while a transfer is in progress */
415  if (true == hDevice->bTransferInProgress) {
417  }
418 #endif
419 
420  /* Set the callback function and param in the device */
421  hDevice->pfCallback = pfCallback;
422  hDevice->pCBParam = pCBParam;
423 
424  return ADI_FEE_SUCCESS;
425 }
426 
427 
458 ADI_FEE_RESULT adi_fee_PageErase (ADI_FEE_HANDLE const hDevice, uint32_t const nPageNumStart, uint32_t const nPageNumEnd, uint32_t* const pHwErrors)
459 
460 {
462 
463  uint32_t page;
464 
465 #ifdef ADI_DEBUG
466 
467  if (true != IsDeviceHandle(hDevice)) {
469  }
470 
471  /* reject while a transfer is in progress */
472  if (true == hDevice->bTransferInProgress) {
474  }
475 
476  uint32_t nRelAddrStart = (nPageNumStart << FEE_PAGE_SHIFT);
477  uint32_t nRelAddrStop = (nPageNumEnd << FEE_PAGE_SHIFT);
478 
479  if ( (nPageNumStart > nPageNumEnd)
480  || (nRelAddrStart >= FEE_FLASH_SIZE)
481  || (nRelAddrStop >= FEE_FLASH_SIZE))
482  {
484  }
485 #endif /* defined (ADI_DEBUG) */
486 
487  for (page = nPageNumStart; page <= nPageNumEnd; page++)
488  {
489  /* Wait until not busy */
490  BusyWait(hDevice, (BITM_FLCC_STAT_CMDBUSY | BITM_FLCC_STAT_WRCLOSE));
491 
492  /* Set the page address */
493  hDevice->pDev->PAGE_ADDR0 = (page << FEE_PAGE_SHIFT);
494 
495  /* Issue a page erase command */
496  result = SendCommand (hDevice, ENUM_FLCC_CMD_ERASEPAGE);
497 
498  /* block on command */
499  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
500 
501  if (result != ADI_FEE_SUCCESS) {
502  break;
503  }
504  }
505 
506  /* copy out any hardware errors... */
507  *pHwErrors = hDevice->feeError;
508  if (0u != hDevice->feeError) {
509  /* return the HW error return code */
511  }
512 
513  return result;
514 }
515 
516 
540 ADI_FEE_RESULT adi_fee_MassErase (ADI_FEE_HANDLE const hDevice, uint32_t* const pHwErrors)
541 {
543 
544 #ifdef ADI_DEBUG
545  if (true != IsDeviceHandle(hDevice)) {
547  }
548 
549  /* reject while a transfer is in progress */
550  if (true == hDevice->bTransferInProgress) {
552  }
553 #endif
554 
555  /* Call the mass erase command */
556  result = SendCommand (hDevice, ENUM_FLCC_CMD_MASSERASE);
557 
558  /* block on command */
559  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
560 
561  /* copy out any hardware errors... */
562  *pHwErrors = hDevice->feeError;
563  if (0u != hDevice->feeError) {
564  /* return the HW error return code */
566  }
567 
568  return result;
569 }
570 
571 
606 ADI_FEE_RESULT adi_fee_Write (ADI_FEE_HANDLE const hDevice, ADI_FEE_TRANSACTION* const pTransaction, uint32_t* const pHwErrors)
607 {
609 
610 #ifdef ADI_DEBUG
611  if (true != IsDeviceHandle(hDevice)) {
613  }
614 
615  /* reject while a transfer is in progress */
616  if (true == hDevice->bTransferInProgress) {
618  }
619 
620  /* check address is 64-bit aligned and data pointer is 32-bit aligned */
621  if ( (((uint32_t)pTransaction->pWriteAddr & 0x7u) != 0u) || ((((uint32_t)pTransaction->pWriteData) & 0x3u) != 0u) )
622  {
623  return ADI_FEE_ERR_ALIGNMENT;
624  }
625 
626  /* make sure size is a multiple of 8 */
627  if ((pTransaction->nSize & 0x7u) != 0u) {
629  }
630 
631  if (true == pTransaction->bUseDma) {
632  /* check for max DMA units (32-bit chunks, i.e., 4 bytes at a whack) */
633  if (DMA_TRANSFER_LIMIT < (pTransaction->nSize / sizeof(uint32_t))) {
635  }
636  }
637 #endif
638 
639  /* reset submit/get safeguard flag */
640  hDevice->bSubmitCalled = false;
641 
642  /* Fill in the transfer params */
643  hDevice->pNextWriteAddress = pTransaction->pWriteAddr;
644  hDevice->pNextReadAddress = pTransaction->pWriteData;
645  hDevice->nRemainingBytes = pTransaction->nSize;
646  hDevice->bUseDma = pTransaction->bUseDma;
647 
648  /* Initiate a transfer */
649  result = InitiateTransfer (hDevice);
650 
651  /* Wait for the completed transfer */
652  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
653 
654  /* issue any flash DMA error status codes... */
655  if (0u != hDevice->dmaError) {
656  return hDevice->dmaError;
657  }
658 
659  /* copy out any hardware errors... */
660  *pHwErrors = hDevice->feeError;
661  if (0u != hDevice->feeError) {
662  /* return the HW error return code */
664  }
665 
666  /* Check for errors in buffer write */
667  if (hDevice->nRemainingBytes != 0u) {
668  return ADI_FEE_ERR_BUFFER_ERR;
669  }
670 
671  return result;
672 }
673 
674 
706 {
708 
709 #ifdef ADI_DEBUG
710  if (true != IsDeviceHandle(hDevice)) {
712  }
713 
714  /* reject while a transfer is in progress */
715  if (true == hDevice->bTransferInProgress) {
717  }
718 
719  /* check address is 64-bit aligned and data pointer is 32-bit aligned */
720  if ( (((uint32_t)pTransaction->pWriteAddr & 0x7u) != 0u) || ((((uint32_t)pTransaction->pWriteData) & 0x3u) != 0u) )
721  {
722  return ADI_FEE_ERR_ALIGNMENT;
723  }
724 
725  /* make sure size is a multiple of 8 */
726  if ((pTransaction->nSize & 0x7u) != 0u) {
728  }
729 
730  if (true == pTransaction->bUseDma) {
731  /* check for max DMA units (32-bit channel width means 4 bytes at a whack) */
732  if (DMA_TRANSFER_LIMIT < (pTransaction->nSize / sizeof(uint32_t))) {
734  }
735  }
736 #endif
737 
738  /* set submit/get safeguard flag */
739  hDevice->bSubmitCalled = true;
740 
741  /* Fill in the transfer params */
742  hDevice->pNextWriteAddress = pTransaction->pWriteAddr;
743  hDevice->pNextReadAddress = pTransaction->pWriteData;
744  hDevice->nRemainingBytes = pTransaction->nSize;
745  hDevice->bUseDma = pTransaction->bUseDma;
746 
747  /* initiate a transfer */
748  result = InitiateTransfer (hDevice);
749 
750  /* no pend here... just return */
751 
752  return result;
753 }
754 
755 
773 ADI_FEE_RESULT adi_fee_IsBufferAvailable (ADI_FEE_HANDLE const hDevice, bool* const pbCompletionState)
774 
775 {
776 #ifdef ADI_DEBUG
777  if (true != IsDeviceHandle(hDevice)) {
779  }
780 
781  if (pbCompletionState == NULL) {
783  }
784 #endif
785 
786  /* fail if not a submit-based transaction */
787  if (false == hDevice->bSubmitCalled) {
789  }
790 
791  if (true == hDevice->bTransferInProgress) {
792  *pbCompletionState = false;
793  } else {
794  *pbCompletionState = true;
795  }
796 
797  return ADI_FEE_SUCCESS;
798 }
799 
800 
828 ADI_FEE_RESULT adi_fee_GetBuffer (ADI_FEE_HANDLE const hDevice, uint32_t* const pHwErrors)
829 
830 {
831 #ifdef ADI_DEBUG
832  if (true != IsDeviceHandle(hDevice)) {
834  }
835 #endif
836 
837  /* fail if not a submit-based transaction */
838  if (false == hDevice->bSubmitCalled) {
840  }
841 
842  /* Pend for the semaphore */
843  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
844 
845  /* issue any flash DMA error status codes... */
846  if (0u != hDevice->dmaError) {
847  return hDevice->dmaError;
848  }
849 
850  /* copy out any hardware errors... */
851  *pHwErrors = hDevice->feeError;
852  if (0u != hDevice->feeError) {
853  /* return the HW error return code */
855  }
856 
857  /* Check for errors in buffer write or transfer still in progress */
858  if ((0u != hDevice->nRemainingBytes) || (true == hDevice->bTransferInProgress)) {
859  return ADI_FEE_ERR_BUFFER_ERR;
860  }
861 
862  return ADI_FEE_SUCCESS;
863 }
864 
865 
887 ADI_FEE_RESULT adi_fee_GetPageNumber (ADI_FEE_HANDLE const hDevice, uint32_t const nAddress, uint32_t* const pnPageNum)
888 {
889 #ifdef ADI_DEBUG
890 
891  if (true != IsDeviceHandle(hDevice)) {
893  }
894 
895  if ( (pnPageNum == NULL)
896  || (nAddress >= FEE_FLASH_SIZE))
897  {
899  }
900 #endif
901 
902  /* Set the page number for the given flash address */
903  *pnPageNum = (nAddress >> FEE_PAGE_SHIFT);
904 
905  return ADI_FEE_SUCCESS;
906 }
907 
908 
927 ADI_FEE_RESULT adi_fee_GetBlockNumber (ADI_FEE_HANDLE const hDevice, uint32_t const nAddress, uint32_t* const pnBlockNum)
928 {
929 #ifdef ADI_DEBUG
930 
931  if (true != IsDeviceHandle(hDevice)) {
933  }
934 
935  if ( (pnBlockNum == NULL)
936  || (nAddress >= FEE_FLASH_SIZE))
937  {
939  }
940 #endif
941 
942  /* Set the block number */
943  *pnBlockNum = (nAddress >> FEE_BLOCK_SHIFT);
944 
945  return ADI_FEE_SUCCESS;
946 }
947 
948 
979 ADI_FEE_RESULT adi_fee_VerifySignature (ADI_FEE_HANDLE const hDevice, uint32_t const nStartPage, uint32_t const nEndPage, uint32_t* const pSigResult, uint32_t* const pHwErrors)
980 
981 {
983 
984 #ifdef ADI_DEBUG
985  if (true != IsDeviceHandle(hDevice)) {
987  }
988 
989  /* reject while a transfer is in progress */
990  if (true == hDevice->bTransferInProgress) {
992  }
993 
994  if ( (pSigResult == NULL)
995  || (nStartPage > nEndPage)
996  || (nStartPage >= FEE_MAX_NUM_PAGES)
997  || (nEndPage >= FEE_MAX_NUM_PAGES)
998  )
999  {
1001  }
1002 #endif
1003 
1004  /* Wait until not busy */
1005  BusyWait (hDevice, (BITM_FLCC_STAT_CMDBUSY | BITM_FLCC_STAT_WRCLOSE));
1006 
1007  /* Set the lower and upper page */
1008  hDevice->pDev->PAGE_ADDR0 = nStartPage << FEE_PAGE_SHIFT;
1009  hDevice->pDev->PAGE_ADDR1 = nEndPage << FEE_PAGE_SHIFT;
1010 
1011  /* Do a SIGN command */
1012  result = SendCommand(hDevice, ENUM_FLCC_CMD_SIGN);
1013 
1014  /* block on command */
1015  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
1016 
1017  /* Return the signature to the application */
1018  if (ADI_FEE_SUCCESS == result) {
1019  *pSigResult = hDevice->pDev->SIGNATURE;
1020  } else {
1021  *pSigResult = 0u;
1022  }
1023 
1024  /* copy out any hardware errors... */
1025  *pHwErrors = hDevice->feeError;
1026  if (0u != hDevice->feeError) {
1027  /* return the HW error return code */
1029  }
1030 
1031  return result;
1032 }
1033 
1034 
1064 ADI_FEE_RESULT adi_fee_WriteProtectBlock (ADI_FEE_HANDLE const hDevice, uint32_t const nBlockNum)
1065 
1066 {
1067 #ifdef ADI_DEBUG
1068  if (true != IsDeviceHandle(hDevice)) {
1070  }
1071 
1072  /* reject while a transfer is in progress */
1073  if (true == hDevice->bTransferInProgress) {
1075  }
1076 
1077  if (nBlockNum > FEE_MAX_NUM_BLOCKS) {
1079  }
1080 #endif
1081 
1082  /* Set the write protection (by clearing the bit) for the given block */
1083  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1084  CLR_BITS (hDevice->pDev->WRPROT, 1u << nBlockNum);
1085  hDevice->pDev->KEY = 0u;
1086 
1087  return ADI_FEE_SUCCESS;
1088 }
1089 
1090 
1109 ADI_FEE_RESULT adi_fee_Sleep (ADI_FEE_HANDLE const hDevice, bool const bSleep)
1110 {
1112 
1113 #ifdef ADI_DEBUG
1114  if (true != IsDeviceHandle(hDevice)) {
1116  }
1117 
1118  /* reject while a transfer is in progress */
1119  if (true == hDevice->bTransferInProgress) {
1121  }
1122 #endif
1123 
1124 
1125  if (true == bSleep) {
1126  result = SendCommand (hDevice, ENUM_FLCC_CMD_SLEEP);
1127  } else {
1128  result = SendCommand (hDevice, ENUM_FLCC_CMD_IDLE);
1129  }
1130 
1131  /* block on command */
1132  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
1133 
1134  return result;
1135 }
1136 
1137 
1155 
1156 {
1157 #ifdef ADI_DEBUG
1158  if (true != IsDeviceHandle(hDevice)) {
1160  }
1161 #endif
1162  /* Issue the command (abort is keyed) directly */
1163  /* (avoid SendCommand() here, as it does a busy wait, which may not clear if we're in a recovery mode) */
1164  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1165  hDevice->pDev->CMD = ENUM_FLCC_CMD_ABORT;
1166  hDevice->pDev->KEY = 0u;
1167 
1168  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
1169 
1170  return ADI_FEE_SUCCESS;
1171 }
1172 
1173 
1191 ADI_FEE_RESULT adi_fee_GetAbortAddr (ADI_FEE_HANDLE const hDevice, uint32_t* const pnAddress)
1192 {
1193 #ifdef ADI_DEBUG
1194  if (true != IsDeviceHandle(hDevice)) {
1196  }
1197 
1198  if (pnAddress == NULL) {
1200  }
1201 #endif
1202 
1203  /* Write the address of the last write abort to the pointer
1204  * supplied by the application
1205  */
1206  *pnAddress = hDevice->pDev->WR_ABORT_ADDR;
1207 
1208  return ADI_FEE_SUCCESS;
1209 }
1210 
1211 
1238 ADI_FEE_RESULT adi_fee_ConfigECC (ADI_FEE_HANDLE const hDevice, uint32_t const nStartPage, bool const bInfoECCEnable)
1239 {
1240  uint32_t nRelAddress = nStartPage << FEE_PAGE_SHIFT;
1241 
1242 #ifdef ADI_DEBUG
1243  if (true != IsDeviceHandle(hDevice)) {
1245  }
1246 
1247  /* reject while a transfer is in progress */
1248  if (true == hDevice->bTransferInProgress) {
1250  }
1251 
1252  if (nStartPage >= FEE_MAX_NUM_PAGES) {
1254  }
1255 #endif
1256 
1257  /* Clear the ECC config bits */
1258  CLR_BITS (hDevice->pDev->ECC_CFG, (BITM_FLCC_ECC_CFG_PTR | BITM_FLCC_ECC_CFG_INFOEN));
1259 
1260  /* Set the start page address in the ECC Cfg register */
1261  hDevice->pDev->ECC_CFG |= (nRelAddress & BITM_FLCC_ECC_CFG_PTR);
1262 
1263  /* enable ECC on info space... if requested */
1264  if (true == bInfoECCEnable) {
1265  SET_BITS (hDevice->pDev->ECC_CFG, BITM_FLCC_ECC_CFG_INFOEN);
1266  }
1267 
1268  return ADI_FEE_SUCCESS;
1269 }
1270 
1271 
1296 ADI_FEE_RESULT adi_fee_EnableECC (ADI_FEE_HANDLE const hDevice, bool const bEnable)
1297 {
1298 #ifdef ADI_DEBUG
1299  if (true != IsDeviceHandle(hDevice)) {
1301  }
1302 
1303  /* reject while a transfer is in progress */
1304  if (true == hDevice->bTransferInProgress) {
1306  }
1307 #endif
1308 
1309  /* manage flash ECC enable */
1310  if (true == bEnable) {
1311  SET_BITS(hDevice->pDev->ECC_CFG, BITM_FLCC_ECC_CFG_EN);
1312  } else {
1313  CLR_BITS(hDevice->pDev->ECC_CFG, BITM_FLCC_ECC_CFG_EN);
1314  }
1315 
1316  return ADI_FEE_SUCCESS;
1317 }
1318 
1319 
1347 
1348 {
1349  uint32_t nBitMask;
1350  int32_t nBitPos;
1351 
1352 #ifdef ADI_DEBUG
1353  if (true != IsDeviceHandle(hDevice)) {
1355  }
1356 
1357  /* reject while a transfer is in progress */
1358  if (true == hDevice->bTransferInProgress) {
1360  }
1361 
1362  /* Check the function parameters */
1363  if ( ( (eEvent != ADI_FEE_ECC_EVENT_TYPE_ERROR)
1364  && (eEvent != ADI_FEE_ECC_EVENT_TYPE_CORRECT))
1365 
1366  || ( (eResponse != ADI_FEE_ECC_RESPONSE_NONE)
1367  && (eResponse != ADI_FEE_ECC_RESPONSE_BUS_ERROR)
1368  && (eResponse != ADI_FEE_ECC_RESPONSE_IRQ))
1369  )
1370  {
1372  }
1373 #endif
1374 
1375  /* Select the correct bit mask and bit pos for the event type */
1376  if (eEvent == ADI_FEE_ECC_EVENT_TYPE_ERROR) {
1377  nBitMask = BITM_FLCC_IEN_ECC_ERROR;
1378  nBitPos = BITP_FLCC_IEN_ECC_ERROR;
1379  }
1380 #if defined (__ADUCM4x50__)
1381  else {
1382  nBitMask = BITM_FLCC_IEN_ECC_CORRECT;
1383  nBitPos = BITP_FLCC_IEN_ECC_CORRECT;
1384  }
1385 #endif
1386 
1387  /* clear the bits */
1388  CLR_BITS (hDevice->pDev->IEN, nBitMask);
1389 
1390  /* set the response */
1391  SET_BITS (hDevice->pDev->IEN, ((uint32_t)eResponse) << nBitPos);
1392 
1393  return ADI_FEE_SUCCESS;
1394 }
1395 
1396 
1416 ADI_FEE_RESULT adi_fee_GetECCErrAddr (ADI_FEE_HANDLE const hDevice, uint32_t* const pnAddress)
1417 
1418 {
1419 #ifdef ADI_DEBUG
1420  if (true != IsDeviceHandle(hDevice)) {
1422  }
1423 
1424  if (pnAddress == NULL) {
1426  }
1427 #endif
1428 
1429  /* Write the address of the last ECC error/correction */
1430  *pnAddress = hDevice->pDev->ECC_ADDR;
1431 
1432  return ADI_FEE_SUCCESS;
1433 }
1434 
1435 
1454 ADI_FEE_RESULT adi_fee_GetECCCorrections (ADI_FEE_HANDLE const hDevice, uint32_t* const pnNumCorrections)
1455 {
1456 
1457 #ifdef ADI_DEBUG
1458  if (true != IsDeviceHandle(hDevice)) {
1460  }
1461 
1462  if (pnNumCorrections == NULL) {
1464  }
1465 #endif
1466 
1467  /* Get the number of ECC Error corrections */
1468  *pnNumCorrections = (hDevice->pDev->STAT & BITM_FLCC_STAT_ECCERRCNT) >> BITP_FLCC_STAT_ECCERRCNT;
1469 
1470  return ADI_FEE_SUCCESS;
1471 }
1472 
1473 
1474 /*======== L O C A L F U N C T I O N D E F I N I T I O N S ========*/
1475 
1476 
1477 /* Send a command to the flash controller... bot don't block on it...
1478  */
1479 static ADI_FEE_RESULT SendCommand (ADI_FEE_HANDLE const hDevice, uint32_t const cmd)
1480 {
1481  /* Wait for the flash to be free */
1482  BusyWait (hDevice, (BITM_FLCC_STAT_CMDBUSY | BITM_FLCC_STAT_WRCLOSE));
1483 
1484  /* Clear the command completion status bit
1485  * by acknowledging it
1486  */
1487  hDevice->pDev->STAT = BITM_FLCC_STAT_CMDCOMP;
1488 
1489  /* Enable command-complete and command-fail interrupt */
1490  SET_BITS(hDevice->pDev->IEN, (BITM_FLCC_IEN_CMDCMPLT | BITM_FLCC_IEN_CMDFAIL));
1491 
1492  /* Issue the command (most commands are keyed) */
1493  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1494  hDevice->pDev->CMD = cmd;
1495  hDevice->pDev->KEY = 0u;
1496 
1497  return ADI_FEE_SUCCESS;
1498 }
1499 
1500 
1501 static ADI_FEE_RESULT InitiatePioTransfer (ADI_FEE_HANDLE const hDevice)
1502 {
1503 
1504  /* use PIO interrupt mode in non-burst-mode (burst-mode only spans 256-bytes).
1505  Initiate the 1st write here, then let the interrupt handler feed
1506  the remaining data as we process "almost-complete" interrupts.
1507  */
1508 
1509  /* write the 1st 64-bits of data */
1510  if (0u != hDevice->nRemainingBytes) {
1511 
1512  /* enable command interrupts */
1513  SET_BITS (hDevice->pDev->IEN, (BITM_FLCC_IEN_WRALCMPLT | BITM_FLCC_IEN_CMDCMPLT | BITM_FLCC_IEN_CMDFAIL));
1514 
1515  /* set initial write address*/
1516  hDevice->pDev->KH_ADDR = (uint32_t)hDevice->pNextWriteAddress;
1517  hDevice->pNextWriteAddress += 2;
1518 
1519  /* set key-hole data registers */
1520  hDevice->pDev->KH_DATA0 = *hDevice->pNextReadAddress;
1521  hDevice->pNextReadAddress++;
1522  hDevice->pDev->KH_DATA1 = *hDevice->pNextReadAddress;
1523  hDevice->pNextReadAddress++;
1524  hDevice->nRemainingBytes -= sizeof(uint64_t);
1525 
1526  /* write the command register which launches the burst write */
1527  hDevice->pDev->CMD = ENUM_FLCC_CMD_WRITE;
1528 
1529  } else {
1531  }
1532 
1533  return ADI_FEE_SUCCESS;
1534 }
1535 
1536 
1537 /* DMA Transfer to FIFO */
1538 static ADI_FEE_RESULT InitiateDmaTransfer (ADI_FEE_HANDLE const hDevice)
1539 {
1540  ADI_DCC_TypeDef* pCCD = pPrimaryCCD; /* pointer to primary DMA descriptor array */
1541 
1542  if (0u != hDevice->nRemainingBytes) {
1543 
1544  /* local channel number */
1545  uint16_t chan = hDevice->pDevInfo->dmaChanNum;
1546 
1547  /* disable endpointer decrement modes */
1548  pADI_DMA0->SRCADDR_CLR = 1u << chan;
1549  pADI_DMA0->DSTADDR_CLR = 1u << chan;
1550 
1551  /* enable the channel */
1552  pADI_DMA0->EN_SET = 1u << chan;
1553 
1554  /* allow flash to request DMA service */
1555  pADI_DMA0->RMSK_CLR = 1u << chan;
1556 
1557  /* activate primary descriptor */
1558  pADI_DMA0->ALT_CLR = 1u << chan;
1559 
1560  /* Note: DMA width is 32-bit for the flash controller, but flash writes require
1561  64-bit writes at a whack. Set DMA R_Power (bus rearbitration rate) to two so
1562  we get two uninterrupted 32-bit DMA writes to the flash with each DMA transfer.
1563  */
1564 
1565  /* set DMA source endpoint */
1566  pCCD += chan; /* offset descriptor pointer to flash channel */
1567  pCCD->DMASRCEND = (uint32_t)hDevice->pNextReadAddress + hDevice->nRemainingBytes - sizeof(uint32_t);
1568 
1569  /* set DMA destination endpoint (no increment) */
1570  pCCD->DMADSTEND = (uint32_t)&hDevice->pDev->KH_DATA1;
1571 
1572  /* set the initial write address */
1573  hDevice->pDev->KH_ADDR = (uint32_t)hDevice->pNextWriteAddress;
1574 
1575  /* set the DMA Control Data Configuration register */
1576  pCCD->DMACDC =
1577  ( ((uint32_t)ADI_DMA_INCR_NONE << DMA_BITP_CTL_DST_INC)
1578  | ((uint32_t)ADI_DMA_INCR_4_BYTE << DMA_BITP_CTL_SRC_INC)
1579  | ((uint32_t)ADI_DMA_WIDTH_4_BYTE << DMA_BITP_CTL_SRC_SIZE)
1580  | ((uint32_t)ADI_DMA_RPOWER_2 << DMA_BITP_CTL_R_POWER)
1581  | (uint32_t)((hDevice->nRemainingBytes/sizeof(uint32_t) - 1u) << DMA_BITP_CTL_N_MINUS_1)
1582  | ((uint32_t)DMA_ENUM_CTL_CYCLE_CTL_BASIC << DMA_BITP_CTL_CYCLE_CTL) );
1583 
1584  /* set auto-increment and DMA enable bits, launching transder */
1585  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1586  SET_BITS (hDevice->pDev->UCFG, (BITM_FLCC_UCFG_AUTOINCEN | BITM_FLCC_UCFG_KHDMAEN));
1587  hDevice->pDev->KEY = 0u;
1588 
1589  } else {
1591  }
1592 
1593  return ADI_FEE_SUCCESS;
1594 }
1595 
1596 
1597 /* Initiate transfer */
1598 static ADI_FEE_RESULT InitiateTransfer (ADI_FEE_HANDLE const hDevice)
1599 {
1601 
1602  /* If a transfer is in progress or if the pending buffers are empty
1603  * the return as there is nothing to be done now
1604  */
1605  if (true == hDevice->bTransferInProgress)
1606  {
1607  return ADI_FEE_ERR_DEVICE_BUSY;
1608  }
1609 
1610  /* Wait for the flash to not be busy */
1611  BusyWait (hDevice, BITM_FLCC_STAT_CMDBUSY);
1612 
1613  /* clear internal errors */
1614  hDevice->feeError = 0u;
1615  hDevice->dmaError = ADI_FEE_SUCCESS;
1616 
1617  /* Set the bool variable to signify that a transfer is in progress */
1618  hDevice->bTransferInProgress = true;
1619 
1620  /* clear any command interrupt enables */
1621  CLR_BITS(hDevice->pDev->IEN, (BITM_FLCC_IEN_WRALCMPLT | BITM_FLCC_IEN_CMDCMPLT | BITM_FLCC_IEN_CMDFAIL));
1622 
1623  /* clear any dangeling command-related status */
1624  hDevice->pDev->STAT = BITM_FLCC_STAT_WRALCOMP | BITM_FLCC_STAT_CMDCOMP | BITM_FLCC_STAT_CMDFAIL;
1625 
1626  /* clear auto-increment and dma enable bits */
1627  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1628  CLR_BITS (hDevice->pDev->UCFG, (BITM_FLCC_UCFG_AUTOINCEN | BITM_FLCC_UCFG_KHDMAEN));
1629  hDevice->pDev->KEY = 0u;
1630 
1631  /* Call the corresponding Transfer functions */
1632  if (true == hDevice->bUseDma) {
1633  result = InitiateDmaTransfer(hDevice);
1634  } else {
1635  result = InitiatePioTransfer(hDevice);
1636  }
1637 
1638  return result;
1639 }
1640 
1641 
1642 /* hide the interrupt handlers from DoxyGen */
1645 /* Flash PIO interrupt handler */
1646 void Flash0_Int_Handler(void)
1647 {
1648  ISR_PROLOG();
1649 
1650  /* post flag */
1651  bool bPost = false;
1652  bool bError = false;
1653 
1654  /* recover the driver handle */
1655  ADI_FEE_HANDLE hDevice = fee_device_info[0].hDevice;
1656 
1657 #ifdef ADI_DEBUG
1658  /* Return if the device is not opened - spurious interrupts */
1659  if (hDevice == NULL) {
1660  return;
1661  }
1662 #endif
1663 
1664  /* update status cache and clear it right away on the controller */
1665  hDevice->FlashStatusCopy = hDevice->pDev->STAT;
1666  hDevice->pDev->STAT = hDevice->FlashStatusCopy;
1667 
1668  /* check for flash device errors */
1669  hDevice->feeError = (ADI_FEE_STATUS_ERROR_MASK & hDevice->FlashStatusCopy);
1670  if (0u != hDevice->feeError) {
1671  bError = true;
1672  }
1673 
1674  /* if no errors */
1675  if (false == bError) {
1676 
1677  if (0u != (BITM_FLCC_STAT_WRALCOMP & hDevice->FlashStatusCopy)) {
1678 
1679  /* write-almost-complete */
1680 
1681  /* if more data to write... */
1682  if (0u != hDevice->nRemainingBytes) {
1683 
1684  /* set next write the address */
1685  hDevice->pDev->KH_ADDR = (uint32_t)hDevice->pNextWriteAddress;
1686  hDevice->pNextWriteAddress += 2;
1687 
1688  /* set next key-hole data */
1689  hDevice->pDev->KH_DATA0 = *hDevice->pNextReadAddress;
1690  hDevice->pNextReadAddress++;
1691  hDevice->pDev->KH_DATA1 = *hDevice->pNextReadAddress;
1692  hDevice->pNextReadAddress++;
1693  hDevice->nRemainingBytes -= sizeof(uint64_t);
1694 
1695  /* initiate next write */
1696  hDevice->pDev->CMD = ENUM_FLCC_CMD_WRITE;
1697 
1698  } else {
1699 
1700  /* no more data to write...
1701  wait for current write-almost-complete status to transition to not busy */
1702  BusyWait (hDevice, BITM_FLCC_STAT_CMDBUSY);
1703 
1704  /* set post flag */
1705  bPost = true;
1706  }
1707 
1708  } else if (0u != (BITM_FLCC_STAT_CMDCOMP & hDevice->FlashStatusCopy)) {
1709 
1710  /* command-complete */
1711 
1712  /* this path is for blocking-mode commands (erase, verify, abort, etc.) */
1713 
1714  /* set post flag */
1715  bPost = true;
1716 
1717  } else {
1718  /* no other interrupt types expected */
1719  }
1720  } else {
1721  /* error(s) detected... set the post flag */
1722  bPost = true;
1723  }
1724 
1725  /* singular post */
1726  if (true == bPost) {
1727 
1728  /* clear the command interrupt enables */
1729  CLR_BITS(hDevice->pDev->IEN, (BITM_FLCC_IEN_WRALCMPLT | BITM_FLCC_IEN_CMDCMPLT | BITM_FLCC_IEN_CMDFAIL));
1730 
1731  /* clear auto-increment and dma enable bits */
1732  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1733  CLR_BITS (hDevice->pDev->UCFG, (BITM_FLCC_UCFG_AUTOINCEN | BITM_FLCC_UCFG_KHDMAEN));
1734  hDevice->pDev->KEY = 0u;
1735 
1736  /* mark transfer complete */
1737  hDevice->bTransferInProgress = false;
1738 
1739  /* dispatch callback (if we have one...) */
1740  if (0u != hDevice->pfCallback) {
1741  if (false == bError) {
1742  /* no error, pass success flag to callback */
1743  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)ADI_FEE_CALLBACK_EVENT_BUFFER_PROCESSED, (void*)NULL);
1744  } else {
1745  /* error condition, pass error flag and error status to callback */
1746  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)ADI_FEE_CALLBACK_EVENT_DEVICE_ERROR, (void*)hDevice->feeError);
1747  }
1748  }
1749 
1750  /* post the semaphore */
1751  SEM_POST(hDevice);
1752  }
1753 
1754  ISR_EPILOG();
1755 }
1756 
1757 
1758 /* Flash DMA interrupt handler */
1759 void DMA_FLASH0_Int_Handler (void)
1760 {
1761  /* rtos prologue */
1762  ISR_PROLOG()
1763  ;
1764 
1765  /* recover the driver handle */
1766  ADI_FEE_HANDLE hDevice = fee_device_info[0].hDevice;
1767 
1768  /* update status cache and clear it right away on the controller */
1769  hDevice->FlashStatusCopy = hDevice->pDev->STAT;
1770  hDevice->pDev->STAT = hDevice->FlashStatusCopy;
1771 
1772  /* capture any hw error status */
1773  hDevice->feeError = (ADI_FEE_STATUS_ERROR_MASK & hDevice->FlashStatusCopy);
1774 
1775  /* clear auto-increment and dma enable bits */
1776  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1777  CLR_BITS (hDevice->pDev->UCFG, (BITM_FLCC_UCFG_AUTOINCEN | BITM_FLCC_UCFG_KHDMAEN));
1778  hDevice->pDev->KEY = 0u;
1779 
1780  /* clear the remaining count, as it should all have gone in one swoop */
1781  hDevice->nRemainingBytes = 0u;
1782 
1783  /* mark transfer complete */
1784  hDevice->bTransferInProgress = false;
1785 
1786  /* dispatch callback (if we have one...) */
1787  if (0u != hDevice->pfCallback) {
1788 
1789  /* no errors, notify success */
1790  if ((0u == hDevice->feeError) && (0u == hDevice->dmaError)) {
1791  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)ADI_FEE_CALLBACK_EVENT_BUFFER_PROCESSED, (void*)NULL);
1792 
1793  /* flash hardware error */
1794  } else if (0u == hDevice->feeError) {
1795  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)ADI_FEE_CALLBACK_EVENT_DEVICE_ERROR, (void*)hDevice->feeError);
1796 
1797  /* flash dma error */
1798  } else if (0u == hDevice->dmaError) {
1799  /* DMA error */
1800  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)hDevice->dmaError, NULL);
1801  } else {
1802  /* no other cases... */
1803  }
1804  }
1805 
1806  /* post the semaphore */
1807  SEM_POST(hDevice);
1808 
1809  ISR_EPILOG();
1810 }
1811 
ADI_FEE_RESULT adi_fee_GetBuffer(ADI_FEE_HANDLE const hDevice, uint32_t *const pHwErrors)
Blocking mode call to await transaction completion.
Definition: adi_flash.c:828
ADI_FEE_RESULT adi_fee_IsBufferAvailable(ADI_FEE_HANDLE const hDevice, bool *const pbCompletionState)
Non-blocking check if a write transaction complete.
Definition: adi_flash.c:773
ADI_DMA_RESULT adi_dma_RegisterCallback(DMA_CHANn_TypeDef const eChannelID, ADI_CALLBACK const pfCallback, void *const pCBParam)
Register a call-back function for a DMA channel.
Definition: adi_dma.c:232
ADI_FEE_RESULT adi_fee_GetECCCorrections(ADI_FEE_HANDLE const hDevice, uint32_t *const pnNumCorrections)
Get the number of 1-bit error corrections.
Definition: adi_flash.c:1454
ADI_FEE_RESULT adi_fee_MassErase(ADI_FEE_HANDLE const hDevice, uint32_t *const pHwErrors)
Erase the entire flash user space memory. This is a blocking call.
Definition: adi_flash.c:540
ADI_FEE_RESULT adi_fee_GetBlockNumber(ADI_FEE_HANDLE const hDevice, uint32_t const nAddress, uint32_t *const pnBlockNum)
Get the zero-based (16kB) block number within which a flash address resides.
Definition: adi_flash.c:927
ADI_FEE_ECC_EVENT_TYPE
Definition: adi_flash.h:115
__IO uint32_t DMASRCEND
Definition: adi_dma.h:176
ADI_FEE_RESULT adi_fee_GetECCErrAddr(ADI_FEE_HANDLE const hDevice, uint32_t *const pnAddress)
Get the address for which the ECC event is detected.
Definition: adi_flash.c:1416
#define ADI_FEE_MEMORY_SIZE
Definition: adi_flash.h:66
ADI_FEE_RESULT adi_fee_GetAbortAddr(ADI_FEE_HANDLE const hDevice, uint32_t *const pnAddress)
Get the address of recently aborted write command.
Definition: adi_flash.c:1191
ADI_FEE_RESULT adi_fee_Sleep(ADI_FEE_HANDLE const hDevice, bool const bSleep)
Sleep or awake the flash controller. This is a blocking call.
Definition: adi_flash.c:1109
#define FEE_MAX_NUM_BLOCKS
Definition: adi_flash.h:99
ADI_FEE_RESULT adi_fee_ConfigECC(ADI_FEE_HANDLE const hDevice, uint32_t const nStartPage, bool const bInfoECCEnable)
Configure ECC start page and enablement.
Definition: adi_flash.c:1238
struct __ADI_FEE_DEV_DATA_TYPE * ADI_FEE_HANDLE
Definition: adi_flash.h:58
ADI_FEE_RESULT adi_fee_Open(uint32_t const nDeviceNum, void *const pMemory, uint32_t const nMemorySize, ADI_FEE_HANDLE *const phDevice)
Open the flash controller.
Definition: adi_flash.c:199
#define FEE_FLASH_SIZE
Definition: adi_flash.h:72
ADI_FEE_RESULT adi_fee_ConfigECCEvents(ADI_FEE_HANDLE const hDevice, ADI_FEE_ECC_EVENT_TYPE const eEvent, ADI_FEE_ECC_RESPONSE const eResponse)
Confifure ECC event response.
Definition: adi_flash.c:1346
ADI_FEE_RESULT adi_fee_WriteProtectBlock(ADI_FEE_HANDLE const hDevice, uint32_t const nBlockNum)
Set write protection on an (16kB) block.
Definition: adi_flash.c:1064
ADI_FEE_RESULT adi_fee_Write(ADI_FEE_HANDLE const hDevice, ADI_FEE_TRANSACTION *const pTransaction, uint32_t *const pHwErrors)
Perform a blocking flash data write operation.
Definition: adi_flash.c:606
ADI_FEE_ECC_RESPONSE
Definition: adi_flash.h:124
#define FEE_PAGE_SHIFT
Definition: adi_flash.h:97
ADI_FEE_RESULT adi_fee_EnableECC(ADI_FEE_HANDLE const hDevice, bool const bEnable)
Enable/Disable user space ECC for the device.
Definition: adi_flash.c:1296
__IO uint32_t DMADSTEND
Definition: adi_dma.h:177
ADI_FEE_RESULT adi_fee_ConfigureWaitStates(ADI_FEE_HANDLE const hDevice, uint8_t numWaitStates)
Configure the flash wait states.
Definition: adi_flash.c:352
ADI_FEE_RESULT
Definition: adi_flash.h:35
ADI_FEE_RESULT adi_fee_RegisterCallback(ADI_FEE_HANDLE const hDevice, ADI_CALLBACK const pfCallback, void *const pCBParam)
Register an application-defined callback function.
Definition: adi_flash.c:407
uint32_t * pWriteAddr
Definition: adi_flash.h:136
ADI_FEE_RESULT adi_fee_SubmitBuffer(ADI_FEE_HANDLE const hDevice, ADI_FEE_TRANSACTION *const pTransaction)
Submit a non-blocking flash data write operation for background processing.
Definition: adi_flash.c:705
#define FEE_BLOCK_SHIFT
Definition: adi_flash.h:73
__IO uint32_t DMACDC
Definition: adi_dma.h:178
void adi_dma_Init(void)
Initialize the DMA peripheral.
Definition: adi_dma.c:155
#define ADI_FEE_NUM_INSTANCES
Definition: adi_flash.h:69
ADI_FEE_RESULT adi_fee_GetPageNumber(ADI_FEE_HANDLE const hDevice, uint32_t const nAddress, uint32_t *const pnPageNum)
Get the zero-based (2kB) page number within which a flash address resides.
Definition: adi_flash.c:887
uint32_t * pWriteData
Definition: adi_flash.h:137
ADI_FEE_RESULT adi_fee_Abort(ADI_FEE_HANDLE const hDevice)
Forcefully ABORT an ongoing flash operation. This is a blocking call.
Definition: adi_flash.c:1154
ADI_FEE_RESULT adi_fee_VerifySignature(ADI_FEE_HANDLE const hDevice, uint32_t const nStartPage, uint32_t const nEndPage, uint32_t *const pSigResult, uint32_t *const pHwErrors)
Generate the CRC signature for a range of flash data page(s). This is a blocking call.
Definition: adi_flash.c:979
#define FEE_MAX_NUM_PAGES
Definition: adi_flash.h:98
ADI_FEE_RESULT adi_fee_PageErase(ADI_FEE_HANDLE const hDevice, uint32_t const nPageNumStart, uint32_t const nPageNumEnd, uint32_t *const pHwErrors)
Erase the given range of (2kB) page(s) within the flash user space memory. This is a blocking call.
Definition: adi_flash.c:458
ADI_FEE_RESULT adi_fee_Close(ADI_FEE_HANDLE const hDevice)
Close the flash controller.
Definition: adi_flash.c:311