ADuCM302x Device Drivers API Reference Manual  Release 3.1.2.0
adi_flash.c
1 
89 /*======== I N C L U D E ========*/
90 
92 #include <adi_processor.h>
93 #include <assert.h>
94 #include <string.h> /* for "memset" */
97 #include <drivers/flash/adi_flash.h>
98 
99 /*============= M I S R A =============*/
100 
101 #ifdef __ICCARM__
102 /*
103 * IAR MISRA C 2004 error suppressions.
104 *
105 * Pm123 (rule 8.5): there shall be no definition of objects or functions in a header file
106 * This isn't a header as such.
107 *
108 * Pm073 (rule 14.7): a function should have a single point of exit
109 * Pm143 (rule 14.7): a function should have a single point of exit at the end of the function
110 * Multiple returns are used for error handling.
111 *
112 * Pm050 (rule 14.2): a null statement shall only occur on a line by itself
113 * Needed for null expansion of ADI_INSTALL_HANDLER and others.
114 *
115 * Pm088 (rule 17.4): pointer arithmetic should not be used.
116 * Relying on pointer arithmetic for buffer handling.
117 *
118 * Pm140 (rule 11.3): a cast should not be performed between a pointer type and an integral type
119 * Required for MMR accesses, determining pointer alignment, and a callback argument.
120 *
121 * Pm026 (rule 12.4): the right hand operand of an && or || operator shall not contain side effects
122 * Side effects being mis-reported due to added volatile storage class.
123 */
124 #pragma diag_suppress=Pm123,Pm073,Pm143,Pm050,Pm088,Pm140,Pm026
125 #endif /* __ICCARM__ */
126 
127 /* pull in internal data structures */
128 #include "adi_flash_data.c"
129 
130 /*======== D E F I N E S ========*/
131 
134 #ifdef ADI_DEBUG
135 #define ASSERT(X) assert(X)
136 #else
137 #define ASSERT(X)
138 #endif
139 
140 /* internal utility macros */
141 #define CLR_BITS(REG, BITS) ((REG) &= ~(BITS))
142 #define SET_BITS(REG, BITS) ((REG) |= (BITS))
143 
144 #ifdef ADI_DEBUG
145 /* Validate Device Handle */
146 static bool IsDeviceHandle (ADI_FEE_HANDLE const hDevice);
147 static bool IsDeviceHandle (ADI_FEE_HANDLE const hDevice)
148 {
149  if ( (fee_device_info[0].hDevice == (hDevice)) && ((hDevice)->pDevInfo->hDevice != NULL) ) {
150  return true;
151  } else {
152  return false;
153  }
154 }
155 #endif
156 
157 /* Wait for specified flash status to be clear */
158 static void BusyWait (ADI_FEE_HANDLE const hDevice, uint32_t const status);
159 static void BusyWait (ADI_FEE_HANDLE const hDevice, uint32_t const status)
160 {
161  while ((hDevice->pDev->STAT & status) != 0u) {}
162 }
163 
164 /* Internal DMA Callback for receiving DMA faults from common DMA error handler */
165 static void dmaCallback(void *pCBParam, uint32_t Event, void *pArg);
166 static void dmaCallback(void *pCBParam, uint32_t Event, void *pArg) {
167 
168  /* recover the device handle */
169  ADI_FEE_HANDLE hDevice = (ADI_FEE_HANDLE)pCBParam;
170 
171  /* save the DMA error */
172  switch (Event) {
174  hDevice->dmaError = ADI_FEE_ERR_DMA_BUS_FAULT;
175  break;
177  hDevice->dmaError = ADI_FEE_ERR_DMA_INVALID_DESCR;
178  break;
179  default:
180  hDevice->dmaError = ADI_FEE_ERR_DMA_UNKNOWN_ERROR;
181  break;
182  }
183 
184  /* transfer is toast... post and callback any waiters */
185 
186  SEM_POST(hDevice);
187 
188  if (0u != hDevice->pfCallback) {
189  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)hDevice->dmaError, (void*)NULL);
190  }
191 }
192 
196 /*======== C O D E ========*/
197 /*
198  * API Implementation
199  */
200 
201 
232 ADI_FEE_RESULT adi_fee_Open (uint32_t const nDeviceNum, void* const pMemory, uint32_t const nMemorySize, ADI_FEE_HANDLE* const phDevice)
233 {
234  ADI_FEE_HANDLE hDevice = NULL; /* initially */
235 
236 #ifdef ADI_DEBUG
237  if (nDeviceNum >= ADI_FEE_NUM_INSTANCES) {
239  }
240 
241  /* verify device is not already open */
242  if (fee_device_info[nDeviceNum].hDevice != NULL) {
244  }
245 
246  if ((pMemory == NULL) || (phDevice == NULL)) {
248  }
249 
250  if (nMemorySize < ADI_FEE_MEMORY_SIZE) {
252  }
253 
254  assert (ADI_FEE_MEMORY_SIZE == sizeof(ADI_FEE_DEV_DATA_TYPE));
255 #endif
256 
257  /* store a bad handle in case of failure */
258  *phDevice = NULL;
259 
260  /* Link user memory (handle) into ADI_FEE_DEVICE_INFO data structure.
261  *
262  * ADI_FEE_DEVICE_INFO <==> ADI_FEE_HANDLE
263  */
264  fee_device_info[nDeviceNum].hDevice = (ADI_FEE_DEV_DATA_TYPE *)pMemory;
265 
266  /* Clear the ADI_FEE_HANDLE memory. This also sets all bool
267  * structure members to false so we do not need to waste cycles
268  * setting these explicitly (e.g. hDevice->bUseDma = false)
269  */
270  memset(pMemory, 0, nMemorySize);
271 
272  /* initialize local device handle and link up device info for this device instance */
273  hDevice = (ADI_FEE_HANDLE)pMemory;
274  hDevice->pDevInfo = &fee_device_info[nDeviceNum];
275 
276  /* Although the ADI_FEE_DEVICE_INFO struct has the physical device pointer
277  * for this instance, copying it to the ADI_FEE_HANDLE struct (in user memory)
278  * will minimize the runtime footprint and cycle count when accessing the FEE
279  * registers.
280  */
281  hDevice->pDev = fee_device_info[nDeviceNum].pDev;
282 
283  /* store a pointer to user's static configuration settings for this device instance */
284  hDevice->pDevInfo->pConfig = (ADI_FEE_CONFIG*)&gConfigInfo[nDeviceNum];
285 
286  /* create the semaphore */
287  SEM_CREATE(hDevice, "fee_sem", ADI_FEE_ERR_SEMAPHORE_FAILED);
288 
289  /* grant keyed access */
290  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
291 
292  /* apply the static initializers */
293  hDevice->pDev->IEN = hDevice->pDevInfo->pConfig->eccIrqEnables;
294  hDevice->pDev->TIME_PARAM0 = hDevice->pDevInfo->pConfig->param0;
295  hDevice->pDev->TIME_PARAM1 = hDevice->pDevInfo->pConfig->param1;
296  hDevice->pDev->ABORT_EN_LO = hDevice->pDevInfo->pConfig->abortEnableLo;
297  hDevice->pDev->ABORT_EN_HI = hDevice->pDevInfo->pConfig->abortEnableHi;
298  hDevice->pDev->ECC_CFG = hDevice->pDevInfo->pConfig->eccConfig;
299 
300  /* clear auto-increment and dma enable bits */
301  CLR_BITS (hDevice->pDev->UCFG, (BITM_FLCC_UCFG_AUTOINCEN | BITM_FLCC_UCFG_KHDMAEN));
302 
303  /* close keyed access */
304  hDevice->pDev->KEY = 0u;
305 
306  /* store device handle into user handle */
307  *phDevice = (ADI_FEE_HANDLE)hDevice;
308 
309  /* initialize DMA service */
310  adi_dma_Init();
311 
312  if (ADI_DMA_SUCCESS != adi_dma_RegisterCallback(hDevice->pDevInfo->dmaChanNum, dmaCallback, (void*)hDevice)) {
313  /* uninitialize flash driver and fail */
314  adi_fee_Close(hDevice);
316  }
317 
318  /* NVIC enables */
319  NVIC_EnableIRQ(hDevice->pDevInfo->pioIrqNum);
320  NVIC_EnableIRQ(hDevice->pDevInfo->dmaIrqNum);
321 
322  /* return success */
323  return ADI_FEE_SUCCESS;
324 }
325 
326 
345 {
346  uint32_t dev;
347 
348 #ifdef ADI_DEBUG
349  if (true != IsDeviceHandle(hDevice)) {
351  }
352 #endif
353 
354  /* Destroy the semaphore */
355  SEM_DELETE(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
356 
357  /* Remove the device handle from the list of possible device instances */
358  for (dev = 0u; dev < ADI_FEE_NUM_INSTANCES; dev++)
359  {
360  if (fee_device_info[dev].hDevice == hDevice)
361  {
362  fee_device_info[dev].hDevice = NULL;
363  break;
364  }
365  }
366 
367  /* NVIC disables */
368  NVIC_DisableIRQ(hDevice->pDevInfo->pioIrqNum);
369  NVIC_DisableIRQ(hDevice->pDevInfo->dmaIrqNum);
370 
371  return ADI_FEE_SUCCESS;
372 }
373 
374 #if defined (__ADUCM4x50__)
375 
385 ADI_FEE_RESULT adi_fee_ConfigureWaitStates (ADI_FEE_HANDLE const hDevice, uint8_t numWaitStates)
386 {
387 #ifdef ADI_DEBUG
388  if (true != IsDeviceHandle(hDevice)) {
390  }
391 #endif
392  /* Flash key protect */
393  *pREG_FLCC0_KEY = ENUM_FLCC_KEY_USERKEY;
394 
395  /* Change flash wait state from 0 to 1. Necessary if system clock is greater than 26 MHz */
396  *pREG_FLCC0_TIME_PARAM1 |= ((((uint32_t)numWaitStates) << BITP_FLCC_TIME_PARAM1_WAITSTATES) & BITM_FLCC_TIME_PARAM1_WAITSTATES);
397 
398  /* Wait until wait states are changed */
399  while (((*pREG_FLCC0_TIME_PARAM1 & BITM_FLCC_TIME_PARAM1_CURWAITSTATES) != (1u << BITP_FLCC_TIME_PARAM1_CURWAITSTATES))){}
400 
401  return ADI_FEE_SUCCESS;
402 }
403 #endif
404 
440 ADI_FEE_RESULT adi_fee_RegisterCallback (ADI_FEE_HANDLE const hDevice, ADI_CALLBACK const pfCallback, void* const pCBParam)
441 {
442 #ifdef ADI_DEBUG
443  if (true != IsDeviceHandle(hDevice)) {
445  }
446 
447  /* reject while a transfer is in progress */
448  if (true == hDevice->bTransferInProgress) {
450  }
451 #endif
452 
453  /* Set the callback function and param in the device */
454  hDevice->pfCallback = pfCallback;
455  hDevice->pCBParam = pCBParam;
456 
457  return ADI_FEE_SUCCESS;
458 }
459 
460 
491 ADI_FEE_RESULT adi_fee_PageErase (ADI_FEE_HANDLE const hDevice, uint32_t const nPageNumStart, uint32_t const nPageNumEnd, uint32_t* const pHwErrors)
492 
493 {
495 
496  uint32_t page;
497 
498 #ifdef ADI_DEBUG
499 
500  if (true != IsDeviceHandle(hDevice)) {
502  }
503 
504  /* reject while a transfer is in progress */
505  if (true == hDevice->bTransferInProgress) {
507  }
508 
509  uint32_t nRelAddrStart = (nPageNumStart << FEE_PAGE_SHIFT);
510  uint32_t nRelAddrStop = (nPageNumEnd << FEE_PAGE_SHIFT);
511 
512  if ( (nPageNumStart > nPageNumEnd)
513  || (nRelAddrStart >= FEE_FLASH_SIZE)
514  || (nRelAddrStop >= FEE_FLASH_SIZE))
515  {
517  }
518 #endif /* defined (ADI_DEBUG) */
519 
520  for (page = nPageNumStart; page <= nPageNumEnd; page++)
521  {
522  /* Wait until not busy */
523  BusyWait(hDevice, (BITM_FLCC_STAT_CMDBUSY | BITM_FLCC_STAT_WRCLOSE));
524 
525  /* Set the page address */
526  hDevice->pDev->PAGE_ADDR0 = (page << FEE_PAGE_SHIFT);
527 
528  /* Issue a page erase command */
529  result = SendCommand (hDevice, ENUM_FLCC_CMD_ERASEPAGE);
530 
531  /* block on command */
532  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
533 
534  if (result != ADI_FEE_SUCCESS) {
535  break;
536  }
537  }
538 
539  /* copy out any hardware errors... */
540  *pHwErrors = hDevice->feeError;
541  if (0u != hDevice->feeError) {
542  /* return the HW error return code */
544  }
545 
546  return result;
547 }
548 
549 
573 ADI_FEE_RESULT adi_fee_MassErase (ADI_FEE_HANDLE const hDevice, uint32_t* const pHwErrors)
574 {
576 
577 #ifdef ADI_DEBUG
578  if (true != IsDeviceHandle(hDevice)) {
580  }
581 
582  /* reject while a transfer is in progress */
583  if (true == hDevice->bTransferInProgress) {
585  }
586 #endif
587 
588  /* Call the mass erase command */
589  result = SendCommand (hDevice, ENUM_FLCC_CMD_MASSERASE);
590 
591  /* block on command */
592  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
593 
594  /* copy out any hardware errors... */
595  *pHwErrors = hDevice->feeError;
596  if (0u != hDevice->feeError) {
597  /* return the HW error return code */
599  }
600 
601  return result;
602 }
603 
604 
639 ADI_FEE_RESULT adi_fee_Write (ADI_FEE_HANDLE const hDevice, ADI_FEE_TRANSACTION* const pTransaction, uint32_t* const pHwErrors)
640 {
642 
643 #ifdef ADI_DEBUG
644  if (true != IsDeviceHandle(hDevice)) {
646  }
647 
648  /* reject while a transfer is in progress */
649  if (true == hDevice->bTransferInProgress) {
651  }
652 
653  /* check address is 64-bit aligned and data pointer is 32-bit aligned */
654  if ( (((uint32_t)pTransaction->pWriteAddr & 0x7u) != 0u) || ((((uint32_t)pTransaction->pWriteData) & 0x3u) != 0u) )
655  {
656  return ADI_FEE_ERR_ALIGNMENT;
657  }
658 
659  /* make sure size is a multiple of 8 */
660  if ((pTransaction->nSize & 0x7u) != 0u) {
662  }
663 
664  if (true == pTransaction->bUseDma) {
665  /* check for max DMA units (32-bit chunks, i.e., 4 bytes at a whack) */
666  if (DMA_TRANSFER_LIMIT < (pTransaction->nSize / sizeof(uint32_t))) {
668  }
669  }
670 #endif
671 
672  /* reset submit/get safeguard flag */
673  hDevice->bSubmitCalled = false;
674 
675  /* Fill in the transfer params */
676  hDevice->pNextWriteAddress = pTransaction->pWriteAddr;
677  hDevice->pNextReadAddress = pTransaction->pWriteData;
678  hDevice->nRemainingBytes = pTransaction->nSize;
679  hDevice->bUseDma = pTransaction->bUseDma;
680 
681  /* Initiate a transfer */
682  result = InitiateTransfer (hDevice);
683 
684  /* Wait for the completed transfer */
685  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
686 
687  /* issue any flash DMA error status codes... */
688  if (0u != hDevice->dmaError) {
689  return hDevice->dmaError;
690  }
691 
692  /* copy out any hardware errors... */
693  *pHwErrors = hDevice->feeError;
694  if (0u != hDevice->feeError) {
695  /* return the HW error return code */
697  }
698 
699  /* Check for errors in buffer write */
700  if (hDevice->nRemainingBytes != 0u) {
701  return ADI_FEE_ERR_BUFFER_ERR;
702  }
703 
704  return result;
705 }
706 
707 
739 {
741 
742 #ifdef ADI_DEBUG
743  if (true != IsDeviceHandle(hDevice)) {
745  }
746 
747  /* reject while a transfer is in progress */
748  if (true == hDevice->bTransferInProgress) {
750  }
751 
752  /* check address is 64-bit aligned and data pointer is 32-bit aligned */
753  if ( (((uint32_t)pTransaction->pWriteAddr & 0x7u) != 0u) || ((((uint32_t)pTransaction->pWriteData) & 0x3u) != 0u) )
754  {
755  return ADI_FEE_ERR_ALIGNMENT;
756  }
757 
758  /* make sure size is a multiple of 8 */
759  if ((pTransaction->nSize & 0x7u) != 0u) {
761  }
762 
763  if (true == pTransaction->bUseDma) {
764  /* check for max DMA units (32-bit channel width means 4 bytes at a whack) */
765  if (DMA_TRANSFER_LIMIT < (pTransaction->nSize / sizeof(uint32_t))) {
767  }
768  }
769 #endif
770 
771  /* set submit/get safeguard flag */
772  hDevice->bSubmitCalled = true;
773 
774  /* Fill in the transfer params */
775  hDevice->pNextWriteAddress = pTransaction->pWriteAddr;
776  hDevice->pNextReadAddress = pTransaction->pWriteData;
777  hDevice->nRemainingBytes = pTransaction->nSize;
778  hDevice->bUseDma = pTransaction->bUseDma;
779 
780  /* initiate a transfer */
781  result = InitiateTransfer (hDevice);
782 
783  /* no pend here... just return */
784 
785  return result;
786 }
787 
788 
806 ADI_FEE_RESULT adi_fee_IsBufferAvailable (ADI_FEE_HANDLE const hDevice, bool* const pbCompletionState)
807 
808 {
809 #ifdef ADI_DEBUG
810  if (true != IsDeviceHandle(hDevice)) {
812  }
813 
814  if (pbCompletionState == NULL) {
816  }
817 #endif
818 
819  /* fail if not a submit-based transaction */
820  if (false == hDevice->bSubmitCalled) {
822  }
823 
824  if (true == hDevice->bTransferInProgress) {
825  *pbCompletionState = false;
826  } else {
827  *pbCompletionState = true;
828  }
829 
830  return ADI_FEE_SUCCESS;
831 }
832 
833 
861 ADI_FEE_RESULT adi_fee_GetBuffer (ADI_FEE_HANDLE const hDevice, uint32_t* const pHwErrors)
862 
863 {
864 #ifdef ADI_DEBUG
865  if (true != IsDeviceHandle(hDevice)) {
867  }
868 #endif
869 
870  /* fail if not a submit-based transaction */
871  if (false == hDevice->bSubmitCalled) {
873  }
874 
875  /* Pend for the semaphore */
876  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
877 
878  /* issue any flash DMA error status codes... */
879  if (0u != hDevice->dmaError) {
880  return hDevice->dmaError;
881  }
882 
883  /* copy out any hardware errors... */
884  *pHwErrors = hDevice->feeError;
885  if (0u != hDevice->feeError) {
886  /* return the HW error return code */
888  }
889 
890  /* Check for errors in buffer write or transfer still in progress */
891  if ((0u != hDevice->nRemainingBytes) || (true == hDevice->bTransferInProgress)) {
892  return ADI_FEE_ERR_BUFFER_ERR;
893  }
894 
895  return ADI_FEE_SUCCESS;
896 }
897 
898 
920 ADI_FEE_RESULT adi_fee_GetPageNumber (ADI_FEE_HANDLE const hDevice, uint32_t const nAddress, uint32_t* const pnPageNum)
921 {
922 #ifdef ADI_DEBUG
923 
924  if (true != IsDeviceHandle(hDevice)) {
926  }
927 
928  if ( (pnPageNum == NULL)
929  || (nAddress >= FEE_FLASH_SIZE))
930  {
932  }
933 #endif
934 
935  /* Set the page number for the given flash address */
936  *pnPageNum = (nAddress >> FEE_PAGE_SHIFT);
937 
938  return ADI_FEE_SUCCESS;
939 }
940 
941 
960 ADI_FEE_RESULT adi_fee_GetBlockNumber (ADI_FEE_HANDLE const hDevice, uint32_t const nAddress, uint32_t* const pnBlockNum)
961 {
962 #ifdef ADI_DEBUG
963 
964  if (true != IsDeviceHandle(hDevice)) {
966  }
967 
968  if ( (pnBlockNum == NULL)
969  || (nAddress >= FEE_FLASH_SIZE))
970  {
972  }
973 #endif
974 
975  /* Set the block number */
976  *pnBlockNum = (nAddress >> FEE_BLOCK_SHIFT);
977 
978  return ADI_FEE_SUCCESS;
979 }
980 
981 
1012 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)
1013 
1014 {
1016 
1017 #ifdef ADI_DEBUG
1018  if (true != IsDeviceHandle(hDevice)) {
1020  }
1021 
1022  /* reject while a transfer is in progress */
1023  if (true == hDevice->bTransferInProgress) {
1025  }
1026 
1027  if ( (pSigResult == NULL)
1028  || (nStartPage > nEndPage)
1029  || (nStartPage >= FEE_MAX_NUM_PAGES)
1030  || (nEndPage >= FEE_MAX_NUM_PAGES)
1031  )
1032  {
1034  }
1035 #endif
1036 
1037  /* Wait until not busy */
1038  BusyWait (hDevice, (BITM_FLCC_STAT_CMDBUSY | BITM_FLCC_STAT_WRCLOSE));
1039 
1040  /* Set the lower and upper page */
1041  hDevice->pDev->PAGE_ADDR0 = nStartPage << FEE_PAGE_SHIFT;
1042  hDevice->pDev->PAGE_ADDR1 = nEndPage << FEE_PAGE_SHIFT;
1043 
1044  /* Do a SIGN command */
1045  result = SendCommand(hDevice, ENUM_FLCC_CMD_SIGN);
1046 
1047  /* block on command */
1048  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
1049 
1050  /* Return the signature to the application */
1051  if (ADI_FEE_SUCCESS == result) {
1052  *pSigResult = hDevice->pDev->SIGNATURE;
1053  } else {
1054  *pSigResult = 0u;
1055  }
1056 
1057  /* copy out any hardware errors... */
1058  *pHwErrors = hDevice->feeError;
1059  if (0u != hDevice->feeError) {
1060  /* return the HW error return code */
1062  }
1063 
1064  return result;
1065 }
1066 
1067 
1097 ADI_FEE_RESULT adi_fee_WriteProtectBlock (ADI_FEE_HANDLE const hDevice, uint32_t const nBlockNum)
1098 
1099 {
1100 #ifdef ADI_DEBUG
1101  if (true != IsDeviceHandle(hDevice)) {
1103  }
1104 
1105  /* reject while a transfer is in progress */
1106  if (true == hDevice->bTransferInProgress) {
1108  }
1109 
1110  if (nBlockNum > FEE_MAX_NUM_BLOCKS) {
1112  }
1113 #endif
1114 
1115  /* Set the write protection (by clearing the bit) for the given block */
1116  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1117  CLR_BITS (hDevice->pDev->WRPROT, 1u << nBlockNum);
1118  hDevice->pDev->KEY = 0u;
1119 
1120  return ADI_FEE_SUCCESS;
1121 }
1122 
1123 
1142 ADI_FEE_RESULT adi_fee_Sleep (ADI_FEE_HANDLE const hDevice, bool const bSleep)
1143 {
1145 
1146 #ifdef ADI_DEBUG
1147  if (true != IsDeviceHandle(hDevice)) {
1149  }
1150 
1151  /* reject while a transfer is in progress */
1152  if (true == hDevice->bTransferInProgress) {
1154  }
1155 #endif
1156 
1157 
1158  if (true == bSleep) {
1159  result = SendCommand (hDevice, ENUM_FLCC_CMD_SLEEP);
1160  } else {
1161  result = SendCommand (hDevice, ENUM_FLCC_CMD_IDLE);
1162  }
1163 
1164  /* block on command */
1165  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
1166 
1167  return result;
1168 }
1169 
1170 
1188 
1189 {
1190 #ifdef ADI_DEBUG
1191  if (true != IsDeviceHandle(hDevice)) {
1193  }
1194 #endif
1195  /* Issue the command (abort is keyed) directly */
1196  /* (avoid SendCommand() here, as it does a busy wait, which may not clear if we're in a recovery mode) */
1197  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1198  hDevice->pDev->CMD = ENUM_FLCC_CMD_ABORT;
1199  hDevice->pDev->KEY = 0u;
1200 
1201  SEM_PEND(hDevice, ADI_FEE_ERR_SEMAPHORE_FAILED);
1202 
1203  return ADI_FEE_SUCCESS;
1204 }
1205 
1206 
1224 ADI_FEE_RESULT adi_fee_GetAbortAddr (ADI_FEE_HANDLE const hDevice, uint32_t* const pnAddress)
1225 {
1226 #ifdef ADI_DEBUG
1227  if (true != IsDeviceHandle(hDevice)) {
1229  }
1230 
1231  if (pnAddress == NULL) {
1233  }
1234 #endif
1235 
1236  /* Write the address of the last write abort to the pointer
1237  * supplied by the application
1238  */
1239  *pnAddress = hDevice->pDev->WR_ABORT_ADDR;
1240 
1241  return ADI_FEE_SUCCESS;
1242 }
1243 
1244 
1271 ADI_FEE_RESULT adi_fee_ConfigECC (ADI_FEE_HANDLE const hDevice, uint32_t const nStartPage, bool const bInfoECCEnable)
1272 {
1273  uint32_t nRelAddress = nStartPage << FEE_PAGE_SHIFT;
1274 
1275 #ifdef ADI_DEBUG
1276  if (true != IsDeviceHandle(hDevice)) {
1278  }
1279 
1280  /* reject while a transfer is in progress */
1281  if (true == hDevice->bTransferInProgress) {
1283  }
1284 
1285  if (nStartPage >= FEE_MAX_NUM_PAGES) {
1287  }
1288 #endif
1289 
1290  /* Clear the ECC config bits */
1291  CLR_BITS (hDevice->pDev->ECC_CFG, (BITM_FLCC_ECC_CFG_PTR | BITM_FLCC_ECC_CFG_INFOEN));
1292 
1293  /* Set the start page address in the ECC Cfg register */
1294  hDevice->pDev->ECC_CFG |= (nRelAddress & BITM_FLCC_ECC_CFG_PTR);
1295 
1296  /* enable ECC on info space... if requested */
1297  if (true == bInfoECCEnable) {
1298  SET_BITS (hDevice->pDev->ECC_CFG, BITM_FLCC_ECC_CFG_INFOEN);
1299  }
1300 
1301  return ADI_FEE_SUCCESS;
1302 }
1303 
1304 
1329 ADI_FEE_RESULT adi_fee_EnableECC (ADI_FEE_HANDLE const hDevice, bool const bEnable)
1330 {
1331 #ifdef ADI_DEBUG
1332  if (true != IsDeviceHandle(hDevice)) {
1334  }
1335 
1336  /* reject while a transfer is in progress */
1337  if (true == hDevice->bTransferInProgress) {
1339  }
1340 #endif
1341 
1342  /* manage flash ECC enable */
1343  if (true == bEnable) {
1344  SET_BITS(hDevice->pDev->ECC_CFG, BITM_FLCC_ECC_CFG_EN);
1345  } else {
1346  CLR_BITS(hDevice->pDev->ECC_CFG, BITM_FLCC_ECC_CFG_EN);
1347  }
1348 
1349  return ADI_FEE_SUCCESS;
1350 }
1351 
1352 
1380 
1381 {
1382  uint32_t nBitMask;
1383  int32_t nBitPos;
1384 
1385 #ifdef ADI_DEBUG
1386  if (true != IsDeviceHandle(hDevice)) {
1388  }
1389 
1390  /* reject while a transfer is in progress */
1391  if (true == hDevice->bTransferInProgress) {
1393  }
1394 
1395  /* Check the function parameters */
1396  if ( ( (eEvent != ADI_FEE_ECC_EVENT_TYPE_ERROR)
1397  && (eEvent != ADI_FEE_ECC_EVENT_TYPE_CORRECT))
1398 
1399  || ( (eResponse != ADI_FEE_ECC_RESPONSE_NONE)
1400  && (eResponse != ADI_FEE_ECC_RESPONSE_BUS_ERROR)
1401  && (eResponse != ADI_FEE_ECC_RESPONSE_IRQ))
1402  )
1403  {
1405  }
1406 #endif
1407 
1408  /* Select the correct bit mask and bit pos for the event type */
1409  if (eEvent == ADI_FEE_ECC_EVENT_TYPE_ERROR) {
1410  nBitMask = BITM_FLCC_IEN_ECC_ERROR;
1411  nBitPos = BITP_FLCC_IEN_ECC_ERROR;
1412  }
1413 #if defined (__ADUCM4x50__)
1414  else {
1415  nBitMask = BITM_FLCC_IEN_ECC_CORRECT;
1416  nBitPos = BITP_FLCC_IEN_ECC_CORRECT;
1417  }
1418 #endif
1419 
1420  /* clear the bits */
1421  CLR_BITS (hDevice->pDev->IEN, nBitMask);
1422 
1423  /* set the response */
1424  SET_BITS (hDevice->pDev->IEN, ((uint32_t)eResponse) << nBitPos);
1425 
1426  return ADI_FEE_SUCCESS;
1427 }
1428 
1429 
1449 ADI_FEE_RESULT adi_fee_GetECCErrAddr (ADI_FEE_HANDLE const hDevice, uint32_t* const pnAddress)
1450 
1451 {
1452 #ifdef ADI_DEBUG
1453  if (true != IsDeviceHandle(hDevice)) {
1455  }
1456 
1457  if (pnAddress == NULL) {
1459  }
1460 #endif
1461 
1462  /* Write the address of the last ECC error/correction */
1463  *pnAddress = hDevice->pDev->ECC_ADDR;
1464 
1465  return ADI_FEE_SUCCESS;
1466 }
1467 
1468 
1487 ADI_FEE_RESULT adi_fee_GetECCCorrections (ADI_FEE_HANDLE const hDevice, uint32_t* const pnNumCorrections)
1488 {
1489 
1490 #ifdef ADI_DEBUG
1491  if (true != IsDeviceHandle(hDevice)) {
1493  }
1494 
1495  if (pnNumCorrections == NULL) {
1497  }
1498 #endif
1499 
1500  /* Get the number of ECC Error corrections */
1501  *pnNumCorrections = (hDevice->pDev->STAT & BITM_FLCC_STAT_ECCERRCNT) >> BITP_FLCC_STAT_ECCERRCNT;
1502 
1503  return ADI_FEE_SUCCESS;
1504 }
1505 
1506 
1507 /*======== L O C A L F U N C T I O N D E F I N I T I O N S ========*/
1508 
1509 
1510 /* Send a command to the flash controller... bot don't block on it...
1511  */
1512 static ADI_FEE_RESULT SendCommand (ADI_FEE_HANDLE const hDevice, uint32_t const cmd)
1513 {
1514  /* Wait for the flash to be free */
1515  BusyWait (hDevice, (BITM_FLCC_STAT_CMDBUSY | BITM_FLCC_STAT_WRCLOSE));
1516 
1517  /* Clear the command completion status bit
1518  * by acknowledging it
1519  */
1520  hDevice->pDev->STAT = BITM_FLCC_STAT_CMDCOMP;
1521 
1522  /* Enable command-complete and command-fail interrupt */
1523  SET_BITS(hDevice->pDev->IEN, (BITM_FLCC_IEN_CMDCMPLT | BITM_FLCC_IEN_CMDFAIL));
1524 
1525  /* Issue the command (most commands are keyed) */
1526  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1527  hDevice->pDev->CMD = cmd;
1528  hDevice->pDev->KEY = 0u;
1529 
1530  return ADI_FEE_SUCCESS;
1531 }
1532 
1533 
1534 static ADI_FEE_RESULT InitiatePioTransfer (ADI_FEE_HANDLE const hDevice)
1535 {
1536 
1537  /* use PIO interrupt mode in non-burst-mode (burst-mode only spans 256-bytes).
1538  Initiate the 1st write here, then let the interrupt handler feed
1539  the remaining data as we process "almost-complete" interrupts.
1540  */
1541 
1542  /* write the 1st 64-bits of data */
1543  if (0u != hDevice->nRemainingBytes) {
1544 
1545  /* enable command interrupts */
1546  SET_BITS (hDevice->pDev->IEN, (BITM_FLCC_IEN_WRALCMPLT | BITM_FLCC_IEN_CMDCMPLT | BITM_FLCC_IEN_CMDFAIL));
1547 
1548  /* set initial write address*/
1549  hDevice->pDev->KH_ADDR = (uint32_t)hDevice->pNextWriteAddress;
1550  hDevice->pNextWriteAddress += 2;
1551 
1552  /* set key-hole data registers */
1553  hDevice->pDev->KH_DATA0 = *hDevice->pNextReadAddress;
1554  hDevice->pNextReadAddress++;
1555  hDevice->pDev->KH_DATA1 = *hDevice->pNextReadAddress;
1556  hDevice->pNextReadAddress++;
1557  hDevice->nRemainingBytes -= sizeof(uint64_t);
1558 
1559  /* write the command register which launches the burst write */
1560  hDevice->pDev->CMD = ENUM_FLCC_CMD_WRITE;
1561 
1562  } else {
1564  }
1565 
1566  return ADI_FEE_SUCCESS;
1567 }
1568 
1569 
1570 /* DMA Transfer to FIFO */
1571 static ADI_FEE_RESULT InitiateDmaTransfer (ADI_FEE_HANDLE const hDevice)
1572 {
1573  ADI_DCC_TypeDef* pCCD = pPrimaryCCD; /* pointer to primary DMA descriptor array */
1574 
1575  if (0u != hDevice->nRemainingBytes) {
1576 
1577  /* local channel number */
1578  uint16_t chan = hDevice->pDevInfo->dmaChanNum;
1579 
1580  /* disable endpointer decrement modes */
1581  pADI_DMA0->SRCADDR_CLR = 1u << chan;
1582  pADI_DMA0->DSTADDR_CLR = 1u << chan;
1583 
1584  /* enable the channel */
1585  pADI_DMA0->EN_SET = 1u << chan;
1586 
1587  /* allow flash to request DMA service */
1588  pADI_DMA0->RMSK_CLR = 1u << chan;
1589 
1590  /* activate primary descriptor */
1591  pADI_DMA0->ALT_CLR = 1u << chan;
1592 
1593  /* Note: DMA width is 32-bit for the flash controller, but flash writes require
1594  64-bit writes at a whack. Set DMA R_Power (bus rearbitration rate) to two so
1595  we get two uninterrupted 32-bit DMA writes to the flash with each DMA transfer.
1596  */
1597 
1598  /* set DMA source endpoint */
1599  pCCD += chan; /* offset descriptor pointer to flash channel */
1600  pCCD->DMASRCEND = (uint32_t)hDevice->pNextReadAddress + hDevice->nRemainingBytes - sizeof(uint32_t);
1601 
1602  /* set DMA destination endpoint (no increment) */
1603  pCCD->DMADSTEND = (uint32_t)&hDevice->pDev->KH_DATA1;
1604 
1605  /* set the initial write address */
1606  hDevice->pDev->KH_ADDR = (uint32_t)hDevice->pNextWriteAddress;
1607 
1608  /* set the DMA Control Data Configuration register */
1609  pCCD->DMACDC =
1610  ( ((uint32_t)ADI_DMA_INCR_NONE << DMA_BITP_CTL_DST_INC)
1611  | ((uint32_t)ADI_DMA_INCR_4_BYTE << DMA_BITP_CTL_SRC_INC)
1612  | ((uint32_t)ADI_DMA_WIDTH_4_BYTE << DMA_BITP_CTL_SRC_SIZE)
1613  | ((uint32_t)ADI_DMA_RPOWER_2 << DMA_BITP_CTL_R_POWER)
1614  | (uint32_t)((hDevice->nRemainingBytes/sizeof(uint32_t) - 1u) << DMA_BITP_CTL_N_MINUS_1)
1615  | ((uint32_t)DMA_ENUM_CTL_CYCLE_CTL_BASIC << DMA_BITP_CTL_CYCLE_CTL) );
1616 
1617  /* set auto-increment and DMA enable bits, launching transder */
1618  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1619  SET_BITS (hDevice->pDev->UCFG, (BITM_FLCC_UCFG_AUTOINCEN | BITM_FLCC_UCFG_KHDMAEN));
1620  hDevice->pDev->KEY = 0u;
1621 
1622  } else {
1624  }
1625 
1626  return ADI_FEE_SUCCESS;
1627 }
1628 
1629 
1630 /* Initiate transfer */
1631 static ADI_FEE_RESULT InitiateTransfer (ADI_FEE_HANDLE const hDevice)
1632 {
1634 
1635  /* If a transfer is in progress or if the pending buffers are empty
1636  * the return as there is nothing to be done now
1637  */
1638  if (true == hDevice->bTransferInProgress)
1639  {
1640  return ADI_FEE_ERR_DEVICE_BUSY;
1641  }
1642 
1643  /* Wait for the flash to not be busy */
1644  BusyWait (hDevice, BITM_FLCC_STAT_CMDBUSY);
1645 
1646  /* clear internal errors */
1647  hDevice->feeError = 0u;
1648  hDevice->dmaError = ADI_FEE_SUCCESS;
1649 
1650  /* Set the bool variable to signify that a transfer is in progress */
1651  hDevice->bTransferInProgress = true;
1652 
1653  /* clear any command interrupt enables */
1654  CLR_BITS(hDevice->pDev->IEN, (BITM_FLCC_IEN_WRALCMPLT | BITM_FLCC_IEN_CMDCMPLT | BITM_FLCC_IEN_CMDFAIL));
1655 
1656  /* clear any dangeling command-related status */
1657  hDevice->pDev->STAT = BITM_FLCC_STAT_WRALCOMP | BITM_FLCC_STAT_CMDCOMP | BITM_FLCC_STAT_CMDFAIL;
1658 
1659  /* clear auto-increment and dma enable bits */
1660  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1661  CLR_BITS (hDevice->pDev->UCFG, (BITM_FLCC_UCFG_AUTOINCEN | BITM_FLCC_UCFG_KHDMAEN));
1662  hDevice->pDev->KEY = 0u;
1663 
1664  /* Call the corresponding Transfer functions */
1665  if (true == hDevice->bUseDma) {
1666  result = InitiateDmaTransfer(hDevice);
1667  } else {
1668  result = InitiatePioTransfer(hDevice);
1669  }
1670 
1671  return result;
1672 }
1673 
1674 
1675 /* hide the interrupt handlers from DoxyGen */
1678 /* Flash PIO interrupt handler */
1679 void Flash0_Int_Handler(void)
1680 {
1681  ISR_PROLOG();
1682 
1683  /* post flag */
1684  bool bPost = false;
1685  bool bError = false;
1686 
1687  /* recover the driver handle */
1688  ADI_FEE_HANDLE hDevice = fee_device_info[0].hDevice;
1689 
1690 #ifdef ADI_DEBUG
1691  /* Return if the device is not opened - spurious interrupts */
1692  if (hDevice == NULL) {
1693  return;
1694  }
1695 #endif
1696 
1697  /* update status cache and clear it right away on the controller */
1698  hDevice->FlashStatusCopy = hDevice->pDev->STAT;
1699  hDevice->pDev->STAT = hDevice->FlashStatusCopy;
1700 
1701  /* check for flash device errors */
1702  hDevice->feeError = (ADI_FEE_STATUS_ERROR_MASK & hDevice->FlashStatusCopy);
1703  if (0u != hDevice->feeError) {
1704  bError = true;
1705  }
1706 
1707  /* if no errors */
1708  if (false == bError) {
1709 
1710  if (0u != (BITM_FLCC_STAT_WRALCOMP & hDevice->FlashStatusCopy)) {
1711 
1712  /* write-almost-complete */
1713 
1714  /* if more data to write... */
1715  if (0u != hDevice->nRemainingBytes) {
1716 
1717  /* set next write the address */
1718  hDevice->pDev->KH_ADDR = (uint32_t)hDevice->pNextWriteAddress;
1719  hDevice->pNextWriteAddress += 2;
1720 
1721  /* set next key-hole data */
1722  hDevice->pDev->KH_DATA0 = *hDevice->pNextReadAddress;
1723  hDevice->pNextReadAddress++;
1724  hDevice->pDev->KH_DATA1 = *hDevice->pNextReadAddress;
1725  hDevice->pNextReadAddress++;
1726  hDevice->nRemainingBytes -= sizeof(uint64_t);
1727 
1728  /* initiate next write */
1729  hDevice->pDev->CMD = ENUM_FLCC_CMD_WRITE;
1730 
1731  } else {
1732 
1733  /* no more data to write...
1734  wait for current write-almost-complete status to transition to not busy */
1735  BusyWait (hDevice, BITM_FLCC_STAT_CMDBUSY);
1736 
1737  /* set post flag */
1738  bPost = true;
1739  }
1740 
1741  } else if (0u != (BITM_FLCC_STAT_CMDCOMP & hDevice->FlashStatusCopy)) {
1742 
1743  /* command-complete */
1744 
1745  /* this path is for blocking-mode commands (erase, verify, abort, etc.) */
1746 
1747  /* set post flag */
1748  bPost = true;
1749 
1750  } else {
1751  /* no other interrupt types expected */
1752  }
1753  } else {
1754  /* error(s) detected... set the post flag */
1755  bPost = true;
1756  }
1757 
1758  /* singular post */
1759  if (true == bPost) {
1760 
1761  /* clear the command interrupt enables */
1762  CLR_BITS(hDevice->pDev->IEN, (BITM_FLCC_IEN_WRALCMPLT | BITM_FLCC_IEN_CMDCMPLT | BITM_FLCC_IEN_CMDFAIL));
1763 
1764  /* clear auto-increment and dma enable bits */
1765  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1766  CLR_BITS (hDevice->pDev->UCFG, (BITM_FLCC_UCFG_AUTOINCEN | BITM_FLCC_UCFG_KHDMAEN));
1767  hDevice->pDev->KEY = 0u;
1768 
1769  /* mark transfer complete */
1770  hDevice->bTransferInProgress = false;
1771 
1772  /* dispatch callback (if we have one...) */
1773  if (0u != hDevice->pfCallback) {
1774  if (false == bError) {
1775  /* no error, pass success flag to callback */
1776  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)ADI_FEE_CALLBACK_EVENT_BUFFER_PROCESSED, (void*)NULL);
1777  } else {
1778  /* error condition, pass error flag and error status to callback */
1779  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)ADI_FEE_CALLBACK_EVENT_DEVICE_ERROR, (void*)hDevice->feeError);
1780  }
1781  }
1782 
1783  /* post the semaphore */
1784  SEM_POST(hDevice);
1785  }
1786 
1787  ISR_EPILOG();
1788 }
1789 
1790 
1791 /* Flash DMA interrupt handler */
1792 void DMA_FLASH0_Int_Handler (void)
1793 {
1794  /* rtos prologue */
1795  ISR_PROLOG()
1796  ;
1797 
1798  /* recover the driver handle */
1799  ADI_FEE_HANDLE hDevice = fee_device_info[0].hDevice;
1800 
1801  /* update status cache and clear it right away on the controller */
1802  hDevice->FlashStatusCopy = hDevice->pDev->STAT;
1803  hDevice->pDev->STAT = hDevice->FlashStatusCopy;
1804 
1805  /* capture any hw error status */
1806  hDevice->feeError = (ADI_FEE_STATUS_ERROR_MASK & hDevice->FlashStatusCopy);
1807 
1808  /* clear auto-increment and dma enable bits */
1809  hDevice->pDev->KEY = ENUM_FLCC_KEY_USERKEY;
1810  CLR_BITS (hDevice->pDev->UCFG, (BITM_FLCC_UCFG_AUTOINCEN | BITM_FLCC_UCFG_KHDMAEN));
1811  hDevice->pDev->KEY = 0u;
1812 
1813  /* clear the remaining count, as it should all have gone in one swoop */
1814  hDevice->nRemainingBytes = 0u;
1815 
1816  /* mark transfer complete */
1817  hDevice->bTransferInProgress = false;
1818 
1819  /* dispatch callback (if we have one...) */
1820  if (0u != hDevice->pfCallback) {
1821 
1822  /* no errors, notify success */
1823  if ((0u == hDevice->feeError) && (0u == hDevice->dmaError)) {
1824  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)ADI_FEE_CALLBACK_EVENT_BUFFER_PROCESSED, (void*)NULL);
1825 
1826  /* flash hardware error */
1827  } else if (0u == hDevice->feeError) {
1828  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)ADI_FEE_CALLBACK_EVENT_DEVICE_ERROR, (void*)hDevice->feeError);
1829 
1830  /* flash dma error */
1831  } else if (0u == hDevice->dmaError) {
1832  /* DMA error */
1833  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)hDevice->dmaError, NULL);
1834  } else {
1835  /* no other cases... */
1836  }
1837  }
1838 
1839  /* post the semaphore */
1840  SEM_POST(hDevice);
1841 
1842  ISR_EPILOG();
1843 }
1844 
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:861
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:806
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:223
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:1487
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:573
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:960
ADI_FEE_ECC_EVENT_TYPE
Definition: adi_flash.h:115
__IO uint32_t DMASRCEND
Definition: adi_dma.h:206
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:1449
#define ADI_FEE_MEMORY_SIZE
Definition: adi_flash.h:99
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:1224
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:1142
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:1271
struct __ADI_FEE_DEV_DATA_TYPE * ADI_FEE_HANDLE
Definition: adi_flash.h:91
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:232
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:1379
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:1097
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:639
ADI_FEE_ECC_RESPONSE
Definition: adi_flash.h:124
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:1329
__IO uint32_t DMADSTEND
Definition: adi_dma.h:207
ADI_FEE_RESULT
Definition: adi_flash.h:68
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:440
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:738
__IO uint32_t DMACDC
Definition: adi_dma.h:208
void adi_dma_Init(void)
Initialize the DMA peripheral.
Definition: adi_dma.c:175
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:920
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:1187
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:1012
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:491
ADI_FEE_RESULT adi_fee_Close(ADI_FEE_HANDLE const hDevice)
Close the flash controller.
Definition: adi_flash.c:344