46 #include <adi_processor.h> 47 #include <rtos_map/adi_rtos_map.h> 119 #include <drivers/crc/adi_crc.h> 120 #include <adi_cyclecount.h> 121 #include "adi_crc_def.h" 139 #pragma diag_suppress=Pm123,Pm088,Pm152,Pm140 145 #define ADI_CRC_NUM_DEVICES (1u) 149 #if (ADI_CRC_CFG_ENABLE_DMA_SUPPORT != 0) 156 #ifndef ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID 157 #define ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID 7 158 #pragma message("ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID implicitly defaulted to 7!") 169 #if (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 0) 170 #define ADI_CFG_CRC_DMA_CHANNEL SIP0_CHANn 171 #define ADI_DMA_CRC_ISR DMA_SIP0_Int_Handler 172 #define ADI_CRC_IRQ_ID DMA0_CH16_DONE_IRQn 173 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 1) 174 #define ADI_CFG_CRC_DMA_CHANNEL SIP1_CHANn 175 #define ADI_DMA_CRC_ISR DMA_SIP1_Int_Handler 176 #define ADI_CRC_IRQ_ID DMA0_CH17_DONE_IRQn 177 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 2) 178 #define ADI_CFG_CRC_DMA_CHANNEL SIP2_CHANn 179 #define ADI_DMA_CRC_ISR DMA_SIP2_Int_Handler 180 #define ADI_CRC_IRQ_ID DMA0_CH18_DONE_IRQn 181 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 3) 182 #define ADI_CFG_CRC_DMA_CHANNEL SIP3_CHANn 183 #define ADI_DMA_CRC_ISR DMA_SIP3_Int_Handler 184 #define ADI_CRC_IRQ_ID DMA0_CH19_DONE_IRQn 185 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 4) 186 #define ADI_CFG_CRC_DMA_CHANNEL SIP4_CHANn 187 #define ADI_DMA_CRC_ISR DMA_SIP4_Int_Handler 188 #define ADI_CRC_IRQ_ID DMA0_CH20_DONE_IRQn 189 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 5) 190 #define ADI_CFG_CRC_DMA_CHANNEL SIP5_CHANn 191 #define ADI_DMA_CRC_ISR DMA_SIP5_Int_Handler 192 #define ADI_CRC_IRQ_ID DMA0_CH21_DONE_IRQn 193 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 6) 194 #define ADI_CFG_CRC_DMA_CHANNEL SIP6_CHANn 195 #define ADI_DMA_CRC_ISR DMA_SIP6_Int_Handler 196 #define ADI_CRC_IRQ_ID DMA0_CH22_DONE_IRQn 197 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 7) 198 #define ADI_CFG_CRC_DMA_CHANNEL SIP7_CHANn 199 #define ADI_DMA_CRC_ISR DMA_SIP7_Int_Handler 200 #define ADI_CRC_IRQ_ID DMA0_CH23_DONE_IRQn 202 #error "Invalid Software DMA channel identifier ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID: it must be between 0 and 7" 210 #define ADI_CRC_VALID_DEVICE_ID(DEVNUM) ((DEVNUM)<(ADI_CRC_NUM_DEVICES)) 213 #define ADI_CRC_DEVICE_IS_IDLE(DEV) (((DEV)->eCrcOpStatus == ADI_CRC_OP_IDLE) ? true : false) 220 static ADI_CRC_INFO crc_device_info[ADI_CRC_NUM_DEVICES] =
228 #define ADI_CRC_INVALID_HANDLE(h) ((NULL == (h)) || (crc_device_info[0].hDevice != (h))) 231 #define ADI_CRC_DEVICE_IN_USE(DEVNUM) ((NULL) != crc_device_info[(DEVNUM)].hDevice) 234 #define HDL_TO_DEVICE_PTR(HDL) ((ADI_CRC_INVALID_HANDLE(HDL)) ? (NULL) : ((ADI_CRC_DEVICE*) (HDL))) 236 #define HDL_TO_DEVICE_PTR(HDL) ((ADI_CRC_DEVICE*) (HDL)) 241 #if (ADI_CRC_NUM_DEVICES!=1u) 242 #error "!!! Current CRC driver implementation can deal with a unique CRC instance !!!" 251 static void crc_ResetRegisters (ADI_CRC_DEVICE *pDevice);
253 #if (ADI_CRC_CFG_ENABLE_DMA_SUPPORT == 0) 257 static ADI_CRC_RESULT crc_ExecuteCoreDrivenOperation (ADI_CRC_DEVICE *pDevice,
void *pCrcBuf, uint32_t NumBytes, uint32_t NumBits);
263 static ADI_CRC_RESULT crc_ExecuteDmaDrivenOperation(ADI_CRC_DEVICE *pDevice,
void *pCrcBuf, uint32_t NumBytes, uint32_t NumBits);
264 static void crc_CalculateCrcForRemaining(ADI_CRC_DEVICE *pDevice, uint8_t *pData, uint32_t NumBytes, uint32_t NumBits);
265 static void CRC_Callback_For_DMA_Err_Int_Handler(
void *pcbparam, uint32_t nEvent,
void *pArg);
266 void ADI_DMA_CRC_ISR(
void);
282 ADI_CRC_INFO *pCrcInfo = (ADI_CRC_INVALID_HANDLE(hDevice))
284 : (&(crc_device_info[0]));
298 static void crc_ResetRegisters(ADI_CRC_DEVICE *pDevice)
302 const uint32_t byte_mirroring_pos = (uint32_t) BITP_CRC_CTL_BYTMIRR;
304 const uint32_t bit_mirroring_pos = (uint32_t) BITP_CRC_CTL_BITMIRR;
309 pDevice->pReg->CTL = ( (byte_mirroring_val << byte_mirroring_pos)
310 | (bit_mirroring_val << bit_mirroring_pos)
312 pDevice->pReg->RESULT = seed_value;
313 pDevice->pReg->POLY = polynomial;
316 #if (ADI_CRC_CFG_ENABLE_DMA_SUPPORT == 0) 331 ADI_CRC_DEVICE *pDevice,
337 uint8_t *pData = (uint8_t *)pCrcBuf;
338 uint32_t lsbFirst = pDevice->pReg->CTL & BITM_CRC_CTL_LSBFIRST;
340 pDevice->pReg->CTL |= (BITM_CRC_CTL_EN);
342 if (((uint32_t)pData & 0x3u) != 0u)
346 while ((NumBytes > 0u) && (((uint32_t)pData & 0x3u) != 0u))
348 pDevice->pReg->IPBYTE = *pData;
356 while (NumBytes >= 4u)
367 nData = (nData << 8) | pData[2];
368 nData = (nData << 8) | pData[1];
369 nData = (nData << 8) | pData[0];
374 nData = (nData << 8) | pData[1];
375 nData = (nData << 8) | pData[2];
376 nData = (nData << 8) | pData[3];
378 pDevice->pReg->IPDATA = nData;
383 while (NumBytes > 0u)
385 pDevice->pReg->IPBYTE = *pData;
392 pDevice->pReg->IPBITS[NumBits] = *pData;
395 pDevice->pReg->CTL &= ~(BITM_CRC_CTL_EN);
396 pDevice->eCrcOpStatus = ADI_CRC_OP_IDLE;
417 ADI_CRC_DEVICE *pDevice,
423 uint8_t *pData = (uint8_t *)pCrcBuf;
424 bool bUseDma =
false;
427 if (!ADI_CRC_VALID_DMA_CHANNEL(ADI_CFG_CRC_DMA_CHANNEL))
436 if ((pDevice->pReg->CTL & BITM_CRC_CTL_LSBFIRST) != 0u)
439 if (((uint32_t)pData & 0x3u) != 0u)
442 pDevice->pReg->CTL |= (BITM_CRC_CTL_EN);
443 while ((NumBytes > 0u) && (((uint32_t)pData & 0x3u) != 0u))
445 pDevice->pReg->IPBYTE = *pData;
449 pDevice->pReg->CTL &= ~(BITM_CRC_CTL_EN);
456 const uint32_t channelId = (uint32_t) ADI_CFG_CRC_DMA_CHANNEL;
457 const uint32_t channelBit = 1ul << channelId;
458 const uint32_t numData = NumBytes / 4u;
459 const uint32_t src = (uint32_t) pData;
460 const uint32_t dst = (uint32_t) &pDevice->pReg->IPDATA;
461 const uint32_t numTransData = ( (numData > DMA_TRANSFER_LIMIT)
465 const uint32_t numTransBytes = (numTransData << 2u);
466 const uint32_t lastDataPos = (numTransBytes - 4u);
468 pDevice->pReg->CTL |= ((uint32_t) BITM_CRC_CTL_EN);
470 pADI_DMA0->EN_SET = channelBit;
471 pADI_DMA0->ALT_CLR = channelBit;
472 pADI_DMA0->SRCADDR_CLR = channelBit;
473 pADI_DMA0->DSTADDR_CLR = channelBit;
475 pPrimaryCCD[channelId].DMADSTEND = dst;
476 pPrimaryCCD[channelId].DMASRCEND = src + lastDataPos;
478 pPrimaryCCD[channelId].DMACDC =
482 | ((numTransData - 1u) << ((uint32_t) DMA_BITP_CTL_N_MINUS_1))
483 | (DMA_ENUM_CTL_CYCLE_CTL_AUTO_REQ << DMA_BITP_CTL_CYCLE_CTL)
485 pDevice->pRemainingData = (
void*)(src + numTransBytes);
486 pDevice->RemainingBytes = NumBytes - numTransBytes;
487 pDevice->RemainingBits = NumBits;
509 const uint32_t channelId = (uint32_t) ADI_CFG_CRC_DMA_CHANNEL;
510 const uint32_t channelBit = 1ul << channelId;
511 const uint32_t src = (uint32_t) pData;
512 const uint32_t dst = (uint32_t) &pDevice->pReg->IPBYTE;
513 const uint32_t numTransData = ( (NumBytes > DMA_TRANSFER_LIMIT)
517 const uint32_t lastDataPos = (numTransData - 1u);
519 pDevice->pReg->CTL |= (BITM_CRC_CTL_EN);
521 pADI_DMA0->EN_SET = channelBit;
522 pADI_DMA0->ALT_CLR = channelBit;
523 pADI_DMA0->SRCADDR_CLR = channelBit;
524 pADI_DMA0->DSTADDR_CLR = channelBit;
526 pPrimaryCCD[channelId].DMADSTEND = dst;
527 pPrimaryCCD[channelId].DMASRCEND = src + lastDataPos;
528 pPrimaryCCD[channelId].DMACDC =
532 | ((numTransData - 1u) << ((uint32_t) DMA_BITP_CTL_N_MINUS_1))
533 | (DMA_ENUM_CTL_CYCLE_CTL_AUTO_REQ << DMA_BITP_CTL_CYCLE_CTL)
535 pDevice->pRemainingData = (
void*) (src + numTransData);
536 pDevice->RemainingBytes = NumBytes - numTransData;
537 pDevice->RemainingBits = NumBits;
545 const uint32_t channelId = (uint32_t) ADI_CFG_CRC_DMA_CHANNEL;
546 const uint32_t channelBit = 1ul << channelId;
547 pADI_DMA0->SWREQ = channelBit;
551 pDevice->pReg->CTL |= (BITM_CRC_CTL_EN);
552 crc_CalculateCrcForRemaining(pDevice, pData, NumBytes, NumBits);
553 pDevice->pReg->CTL &= ~(BITM_CRC_CTL_EN);
554 if(pDevice->pfCallback != NULL)
556 pDevice->pfCallback(pDevice->pCBParam, (uint32_t) ADI_CRC_EVENT_BUFFER_PROCESSED, pData);
558 pDevice->eCrcOpStatus = ADI_CRC_OP_IDLE;
574 static void crc_CalculateCrcForRemaining(ADI_CRC_DEVICE *pDevice, uint8_t *pData, uint32_t NumBytes, uint32_t NumBits)
577 while (NumBytes > 0u)
579 pDevice->pReg->IPBYTE = *pData;
587 pDevice->pReg->IPBITS[NumBits] = *pData;
597 static void CRC_Callback_For_DMA_Err_Int_Handler(
void *pcbparam, uint32_t nEvent,
void *pArg)
599 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(pcbparam);
604 pDevice->eCrcOpStatus = ADI_CRC_OP_IDLE;
605 pDevice->pReg->CTL &= (uint32_t)(~(BITM_CRC_CTL_EN));
617 void ADI_DMA_CRC_ISR(
void)
621 if (ADI_CRC_DEVICE_IN_USE(0))
623 ADI_CRC_DEVICE * pDevice = HDL_TO_DEVICE_PTR(crc_device_info[0].hDevice);
626 uint8_t *pData = (uint8_t *)(pDevice->pRemainingData);
627 uint32_t NumBytes = pDevice->RemainingBytes;
628 uint32_t NumBits = pDevice->RemainingBits;
629 bool finishing = (NumBytes < 4u);
634 ADI_CRC_RESULT result = pDevice->pfSubmitBuffer(pDevice, pData, NumBytes, NumBits);
646 crc_CalculateCrcForRemaining(pDevice, pData, NumBytes, NumBits);
650 if(pDevice->pfCallback != NULL)
652 pDevice->pfCallback(pDevice->pCBParam, (uint32_t) ADI_CRC_EVENT_BUFFER_PROCESSED, NULL);
654 pDevice->eCrcOpStatus = ADI_CRC_OP_IDLE;
660 #if defined(ADI_CYCLECOUNT_CRC_ISR_ENABLED) && (ADI_CYCLECOUNT_CRC_ISR_ENABLED == 1u) 699 ADI_CRC_DEVICE *pDevice = (ADI_CRC_DEVICE*) pMemory;
702 if (!ADI_CRC_VALID_DEVICE_ID(DeviceNum))
706 else if (ADI_CRC_DEVICE_IN_USE(DeviceNum))
722 memset(pMemory, 0, MemorySize);
724 ADI_INT_STATUS_ALLOC();
725 ADI_ENTER_CRITICAL_REGION();
729 pDevice->pReg = crc_device_info[DeviceNum].pReg;
731 ADI_EXIT_CRITICAL_REGION();
733 crc_ResetRegisters(pDevice);
734 *phDevice = crc_device_info[DeviceNum].hDevice;
736 #if (ADI_CRC_CFG_ENABLE_DMA_SUPPORT == 0) 738 pDevice->pfSubmitBuffer = &crc_ExecuteCoreDrivenOperation;
742 pDevice->pfSubmitBuffer = &crc_ExecuteDmaDrivenOperation;
754 NVIC_EnableIRQ(ADI_CRC_IRQ_ID);
773 ADI_CRC_INFO *pCrcInfo = crc_DeviceInfo(hDevice);
775 if (NULL == pCrcInfo)
782 #if (ADI_CRC_CFG_ENABLE_DMA_SUPPORT != 0) 783 NVIC_DisableIRQ(ADI_CRC_IRQ_ID);
794 pCrcInfo->hDevice = NULL;
818 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
825 else if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
833 pDevice->pReg->CTL |= (BITM_CRC_CTL_BITMIRR);
837 pDevice->pReg->CTL &= (uint32_t)(~(BITM_CRC_CTL_BITMIRR));
861 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
868 else if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
876 pDevice->pReg->CTL |= (BITM_CRC_CTL_BYTMIRR);
880 pDevice->pReg->CTL &= (uint32_t)(~(BITM_CRC_CTL_BYTMIRR));
906 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
913 else if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
921 pDevice->pReg->CTL |= (BITM_CRC_CTL_LSBFIRST);
925 pDevice->pReg->CTL &= ~(BITM_CRC_CTL_LSBFIRST);
949 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
956 else if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
964 pDevice->pReg->CTL |= BITM_CRC_CTL_W16SWP;
968 pDevice->pReg->CTL &= ~BITM_CRC_CTL_W16SWP;
990 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
997 else if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
1004 pDevice->pReg->RESULT = CrcSeedVal;
1023 uint32_t PolynomialVal)
1026 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
1029 if (NULL == pDevice)
1033 else if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
1040 pDevice->pReg->POLY = PolynomialVal;
1075 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
1081 else if (NULL == pDevice)
1085 else if (((pDevice->pReg->CTL & BITM_CRC_CTL_REVID) == 0u) && (NumBits != 0u))
1090 if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
1097 pDevice->eCrcOpStatus = ADI_CRC_OP_IN_PROGRESS;
1098 result = pDevice->pfSubmitBuffer(pDevice, pCrcBuf, NumBytes, NumBits);
1121 bool *pbCrcInProgress)
1124 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
1127 if (NULL == pDevice)
1135 if ((pDevice)->eCrcOpStatus == ADI_CRC_OP_IN_PROGRESS)
1137 *pbCrcInProgress =
true;
1142 *pbCrcInProgress =
false;
1172 uint32_t *pFinalCrcVal)
1175 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
1178 if (NULL == pDevice)
1186 *pFinalCrcVal = pDevice->pReg->RESULT;
1187 pDevice->pReg->RESULT = seed_value;
1205 uint32_t *pCurrentCrcVal)
1208 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
1211 if (NULL == pDevice)
1218 *pCurrentCrcVal = pDevice->pReg->RESULT;
1251 ADI_CALLBACK pfCallback,
1252 void *
const pCBParam)
1255 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
1257 ADI_INT_STATUS_ALLOC();
1258 ADI_ENTER_CRITICAL_REGION();
1261 if (NULL == pDevice)
1269 pDevice->pfCallback = pfCallback;
1270 pDevice->pCBParam = pCBParam;
1273 ADI_EXIT_CRITICAL_REGION();
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.
#define ADI_CFG_CRC_SEED_VALUE
struct __ADI_CRC_DEVICE * ADI_CRC_HANDLE
#define ADI_CYCLECOUNT_STORE(id)
ADI_CRC_RESULT adi_crc_GetCurrentCrcVal(ADI_CRC_HANDLE const hDevice, uint32_t *pCurrentCrcVal)
Gets the current/intermediate CRC result computed for a data stream.
ADI_CRC_RESULT adi_crc_RegisterCallback(ADI_CRC_HANDLE const hDevice, ADI_CALLBACK pfCallback, void *const pCBParam)
Registers or unregisters a callback with the CRC device.
#define ADI_CRC_MEMORY_SIZE
ADI_CRC_RESULT adi_crc_SetByteMirroring(ADI_CRC_HANDLE const hDevice, const bool bEnable)
Set the byte mirroring. This function should be called only when device is disabled.
ADI_CRC_RESULT adi_crc_SetPolynomialVal(ADI_CRC_HANDLE const hDevice, uint32_t PolynomialVal)
Sets the 32-bit polynomial for CRC operations.
ADI_CRC_RESULT adi_crc_SetLSBFirst(ADI_CRC_HANDLE const hDevice, const bool bEnable)
Enable the LSB first.
ADI_CRC_RESULT adi_crc_Open(uint32_t DeviceNum, void *pMemory, uint32_t MemorySize, ADI_CRC_HANDLE *phDevice)
Opens a CRC device instance.
ADI_CRC_RESULT adi_crc_IsCrcInProgress(ADI_CRC_HANDLE const hDevice, bool *pbCrcInProgress)
Gets the current CRC peripheral status.
ADI_CRC_RESULT adi_crc_Close(ADI_CRC_HANDLE const hDevice)
Closes CRC device instance opened for use.
ADI_CRC_RESULT adi_crc_GetFinalCrcVal(ADI_CRC_HANDLE const hDevice, uint32_t *pFinalCrcVal)
Gets the final CRC result computed for a data stream.
ADI_CRC_RESULT adi_crc_EnableWordSwap(ADI_CRC_HANDLE const hDevice, const bool bEnable)
To enable/disable the word Swap. This function should be called only when device is disabled...
ADI_CRC_RESULT adi_crc_SetCrcSeedVal(ADI_CRC_HANDLE const hDevice, uint32_t CrcSeedVal)
Sets the initial seed value for the CRC operation that is about to take place.
ADI_CRC_RESULT adi_crc_Compute(ADI_CRC_HANDLE const hDevice, void *pCrcBuf, uint32_t NumBytes, uint32_t NumBits)
Submits data buffer for CRC computation.
#define ADI_CFG_CRC_ENABLE_BIT_MIRRORING
void adi_dma_Init(void)
Initialize the DMA peripheral.
#define ADI_CFG_CRC_ENABLE_BYTE_MIRRORING
#define ADI_CFG_CRC_POLYNOMIAL
#define ADI_CYCLECOUNT_ISR_CRC
ADI_CRC_RESULT adi_crc_SetBitMirroring(ADI_CRC_HANDLE const hDevice, const bool bEnable)
Set the bit mirroring. This function should be called only when device is idle, i.e. when no data are being processd by the CRC.