15 #include <adi_processor.h> 16 #include <rtos_map/adi_rtos_map.h> 88 #include <drivers/crc/adi_crc.h> 89 #include <adi_cyclecount.h> 90 #include "adi_crc_def.h" 108 #pragma diag_suppress=Pm123,Pm088,Pm152,Pm140 114 #define ADI_CRC_NUM_DEVICES (1u) 118 #if (ADI_CRC_CFG_ENABLE_DMA_SUPPORT != 0) 125 #ifndef ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID 126 #define ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID 7 127 #pragma message("ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID implicitly defaulted to 7!") 138 #if (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 0) 139 #define ADI_CFG_CRC_DMA_CHANNEL SIP0_CHANn 140 #define ADI_DMA_CRC_ISR DMA_SIP0_Int_Handler 141 #define ADI_CRC_IRQ_ID DMA0_CH16_DONE_IRQn 142 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 1) 143 #define ADI_CFG_CRC_DMA_CHANNEL SIP1_CHANn 144 #define ADI_DMA_CRC_ISR DMA_SIP1_Int_Handler 145 #define ADI_CRC_IRQ_ID DMA0_CH17_DONE_IRQn 146 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 2) 147 #define ADI_CFG_CRC_DMA_CHANNEL SIP2_CHANn 148 #define ADI_DMA_CRC_ISR DMA_SIP2_Int_Handler 149 #define ADI_CRC_IRQ_ID DMA0_CH18_DONE_IRQn 150 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 3) 151 #define ADI_CFG_CRC_DMA_CHANNEL SIP3_CHANn 152 #define ADI_DMA_CRC_ISR DMA_SIP3_Int_Handler 153 #define ADI_CRC_IRQ_ID DMA0_CH19_DONE_IRQn 154 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 4) 155 #define ADI_CFG_CRC_DMA_CHANNEL SIP4_CHANn 156 #define ADI_DMA_CRC_ISR DMA_SIP4_Int_Handler 157 #define ADI_CRC_IRQ_ID DMA0_CH20_DONE_IRQn 158 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 5) 159 #define ADI_CFG_CRC_DMA_CHANNEL SIP5_CHANn 160 #define ADI_DMA_CRC_ISR DMA_SIP5_Int_Handler 161 #define ADI_CRC_IRQ_ID DMA0_CH21_DONE_IRQn 162 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 6) 163 #define ADI_CFG_CRC_DMA_CHANNEL SIP6_CHANn 164 #define ADI_DMA_CRC_ISR DMA_SIP6_Int_Handler 165 #define ADI_CRC_IRQ_ID DMA0_CH22_DONE_IRQn 166 #elif (ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID == 7) 167 #define ADI_CFG_CRC_DMA_CHANNEL SIP7_CHANn 168 #define ADI_DMA_CRC_ISR DMA_SIP7_Int_Handler 169 #define ADI_CRC_IRQ_ID DMA0_CH23_DONE_IRQn 171 #error "Invalid Software DMA channel identifier ADI_CFG_CRC_SOFTWARE_DMA_CHANNEL_ID: it must be between 0 and 7" 179 #define ADI_CRC_VALID_DEVICE_ID(DEVNUM) ((DEVNUM)<(ADI_CRC_NUM_DEVICES)) 182 #define ADI_CRC_DEVICE_IS_IDLE(DEV) (((DEV)->eCrcOpStatus == ADI_CRC_OP_IDLE) ? true : false) 189 static ADI_CRC_INFO crc_device_info[ADI_CRC_NUM_DEVICES] =
197 #define ADI_CRC_INVALID_HANDLE(h) ((NULL == (h)) || (crc_device_info[0].hDevice != (h))) 200 #define ADI_CRC_DEVICE_IN_USE(DEVNUM) ((NULL) != crc_device_info[(DEVNUM)].hDevice) 203 #define HDL_TO_DEVICE_PTR(HDL) ((ADI_CRC_INVALID_HANDLE(HDL)) ? (NULL) : ((ADI_CRC_DEVICE*) (HDL))) 205 #define HDL_TO_DEVICE_PTR(HDL) ((ADI_CRC_DEVICE*) (HDL)) 210 #if (ADI_CRC_NUM_DEVICES!=1u) 211 #error "!!! Current CRC driver implementation can deal with a unique CRC instance !!!" 220 static void crc_ResetRegisters (ADI_CRC_DEVICE *pDevice);
222 #if (ADI_CRC_CFG_ENABLE_DMA_SUPPORT == 0) 226 static ADI_CRC_RESULT crc_ExecuteCoreDrivenOperation (ADI_CRC_DEVICE *pDevice,
void *pCrcBuf, uint32_t NumBytes, uint32_t NumBits);
232 static ADI_CRC_RESULT crc_ExecuteDmaDrivenOperation(ADI_CRC_DEVICE *pDevice,
void *pCrcBuf, uint32_t NumBytes, uint32_t NumBits);
233 static void crc_CalculateCrcForRemaining(ADI_CRC_DEVICE *pDevice, uint8_t *pData, uint32_t NumBytes, uint32_t NumBits);
234 static void CRC_Callback_For_DMA_Err_Int_Handler(
void *pcbparam, uint32_t nEvent,
void *pArg);
235 void ADI_DMA_CRC_ISR(
void);
251 ADI_CRC_INFO *pCrcInfo = (ADI_CRC_INVALID_HANDLE(hDevice))
253 : (&(crc_device_info[0]));
267 static void crc_ResetRegisters(ADI_CRC_DEVICE *pDevice)
271 const uint32_t byte_mirroring_pos = (uint32_t) BITP_CRC_CTL_BYTMIRR;
273 const uint32_t bit_mirroring_pos = (uint32_t) BITP_CRC_CTL_BITMIRR;
278 pDevice->pReg->CTL = ( (byte_mirroring_val << byte_mirroring_pos)
279 | (bit_mirroring_val << bit_mirroring_pos)
281 pDevice->pReg->RESULT = seed_value;
282 pDevice->pReg->POLY = polynomial;
285 #if (ADI_CRC_CFG_ENABLE_DMA_SUPPORT == 0) 300 ADI_CRC_DEVICE *pDevice,
306 uint8_t *pData = (uint8_t *)pCrcBuf;
307 uint32_t lsbFirst = pDevice->pReg->CTL & BITM_CRC_CTL_LSBFIRST;
309 pDevice->pReg->CTL |= (BITM_CRC_CTL_EN);
311 if (((uint32_t)pData & 0x3u) != 0u)
315 while ((NumBytes > 0u) && (((uint32_t)pData & 0x3u) != 0u))
317 pDevice->pReg->IPBYTE = *pData;
325 while (NumBytes >= 4u)
336 nData = (nData << 8) | pData[2];
337 nData = (nData << 8) | pData[1];
338 nData = (nData << 8) | pData[0];
343 nData = (nData << 8) | pData[1];
344 nData = (nData << 8) | pData[2];
345 nData = (nData << 8) | pData[3];
347 pDevice->pReg->IPDATA = nData;
352 while (NumBytes > 0u)
354 pDevice->pReg->IPBYTE = *pData;
361 pDevice->pReg->IPBITS[NumBits] = *pData;
364 pDevice->pReg->CTL &= ~(BITM_CRC_CTL_EN);
365 pDevice->eCrcOpStatus = ADI_CRC_OP_IDLE;
386 ADI_CRC_DEVICE *pDevice,
392 uint8_t *pData = (uint8_t *)pCrcBuf;
393 bool bUseDma =
false;
396 if (!ADI_CRC_VALID_DMA_CHANNEL(ADI_CFG_CRC_DMA_CHANNEL))
405 if ((pDevice->pReg->CTL & BITM_CRC_CTL_LSBFIRST) != 0u)
408 if (((uint32_t)pData & 0x3u) != 0u)
411 pDevice->pReg->CTL |= (BITM_CRC_CTL_EN);
412 while ((NumBytes > 0u) && (((uint32_t)pData & 0x3u) != 0u))
414 pDevice->pReg->IPBYTE = *pData;
418 pDevice->pReg->CTL &= ~(BITM_CRC_CTL_EN);
425 const uint32_t channelId = (uint32_t) ADI_CFG_CRC_DMA_CHANNEL;
426 const uint32_t channelBit = 1ul << channelId;
427 const uint32_t numData = NumBytes / 4u;
428 const uint32_t src = (uint32_t) pData;
429 const uint32_t dst = (uint32_t) &pDevice->pReg->IPDATA;
430 const uint32_t numTransData = ( (numData > DMA_TRANSFER_LIMIT)
434 const uint32_t numTransBytes = (numTransData << 2u);
435 const uint32_t lastDataPos = (numTransBytes - 4u);
437 pDevice->pReg->CTL |= ((uint32_t) BITM_CRC_CTL_EN);
439 pADI_DMA0->EN_SET = channelBit;
440 pADI_DMA0->ALT_CLR = channelBit;
441 pADI_DMA0->SRCADDR_CLR = channelBit;
442 pADI_DMA0->DSTADDR_CLR = channelBit;
444 pPrimaryCCD[channelId].DMADSTEND = dst;
445 pPrimaryCCD[channelId].DMASRCEND = src + lastDataPos;
447 pPrimaryCCD[channelId].DMACDC =
451 | ((numTransData - 1u) << ((uint32_t) DMA_BITP_CTL_N_MINUS_1))
452 | (DMA_ENUM_CTL_CYCLE_CTL_AUTO_REQ << DMA_BITP_CTL_CYCLE_CTL)
454 pDevice->pRemainingData = (
void*)(src + numTransBytes);
455 pDevice->RemainingBytes = NumBytes - numTransBytes;
456 pDevice->RemainingBits = NumBits;
478 const uint32_t channelId = (uint32_t) ADI_CFG_CRC_DMA_CHANNEL;
479 const uint32_t channelBit = 1ul << channelId;
480 const uint32_t src = (uint32_t) pData;
481 const uint32_t dst = (uint32_t) &pDevice->pReg->IPBYTE;
482 const uint32_t numTransData = ( (NumBytes > DMA_TRANSFER_LIMIT)
486 const uint32_t lastDataPos = (numTransData - 1u);
488 pDevice->pReg->CTL |= (BITM_CRC_CTL_EN);
490 pADI_DMA0->EN_SET = channelBit;
491 pADI_DMA0->ALT_CLR = channelBit;
492 pADI_DMA0->SRCADDR_CLR = channelBit;
493 pADI_DMA0->DSTADDR_CLR = channelBit;
495 pPrimaryCCD[channelId].DMADSTEND = dst;
496 pPrimaryCCD[channelId].DMASRCEND = src + lastDataPos;
497 pPrimaryCCD[channelId].DMACDC =
501 | ((numTransData - 1u) << ((uint32_t) DMA_BITP_CTL_N_MINUS_1))
502 | (DMA_ENUM_CTL_CYCLE_CTL_AUTO_REQ << DMA_BITP_CTL_CYCLE_CTL)
504 pDevice->pRemainingData = (
void*) (src + numTransData);
505 pDevice->RemainingBytes = NumBytes - numTransData;
506 pDevice->RemainingBits = NumBits;
514 const uint32_t channelId = (uint32_t) ADI_CFG_CRC_DMA_CHANNEL;
515 const uint32_t channelBit = 1ul << channelId;
516 pADI_DMA0->SWREQ = channelBit;
520 pDevice->pReg->CTL |= (BITM_CRC_CTL_EN);
521 crc_CalculateCrcForRemaining(pDevice, pData, NumBytes, NumBits);
522 pDevice->pReg->CTL &= ~(BITM_CRC_CTL_EN);
523 if(pDevice->pfCallback != NULL)
525 pDevice->pfCallback(pDevice->pCBParam, (uint32_t) ADI_CRC_EVENT_BUFFER_PROCESSED, pData);
527 pDevice->eCrcOpStatus = ADI_CRC_OP_IDLE;
543 static void crc_CalculateCrcForRemaining(ADI_CRC_DEVICE *pDevice, uint8_t *pData, uint32_t NumBytes, uint32_t NumBits)
546 while (NumBytes > 0u)
548 pDevice->pReg->IPBYTE = *pData;
556 pDevice->pReg->IPBITS[NumBits] = *pData;
566 static void CRC_Callback_For_DMA_Err_Int_Handler(
void *pcbparam, uint32_t nEvent,
void *pArg)
568 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(pcbparam);
573 pDevice->eCrcOpStatus = ADI_CRC_OP_IDLE;
574 pDevice->pReg->CTL &= (uint32_t)(~(BITM_CRC_CTL_EN));
586 void ADI_DMA_CRC_ISR(
void)
590 if (ADI_CRC_DEVICE_IN_USE(0))
592 ADI_CRC_DEVICE * pDevice = HDL_TO_DEVICE_PTR(crc_device_info[0].hDevice);
595 uint8_t *pData = (uint8_t *)(pDevice->pRemainingData);
596 uint32_t NumBytes = pDevice->RemainingBytes;
597 uint32_t NumBits = pDevice->RemainingBits;
598 bool finishing = (NumBytes < 4u);
603 ADI_CRC_RESULT result = pDevice->pfSubmitBuffer(pDevice, pData, NumBytes, NumBits);
615 crc_CalculateCrcForRemaining(pDevice, pData, NumBytes, NumBits);
619 if(pDevice->pfCallback != NULL)
621 pDevice->pfCallback(pDevice->pCBParam, (uint32_t) ADI_CRC_EVENT_BUFFER_PROCESSED, NULL);
623 pDevice->eCrcOpStatus = ADI_CRC_OP_IDLE;
629 #if defined(ADI_CYCLECOUNT_CRC_ISR_ENABLED) && (ADI_CYCLECOUNT_CRC_ISR_ENABLED == 1u) 668 ADI_CRC_DEVICE *pDevice = (ADI_CRC_DEVICE*) pMemory;
671 if (!ADI_CRC_VALID_DEVICE_ID(DeviceNum))
675 else if (ADI_CRC_DEVICE_IN_USE(DeviceNum))
691 memset(pMemory, 0, MemorySize);
693 ADI_INT_STATUS_ALLOC();
694 ADI_ENTER_CRITICAL_REGION();
698 pDevice->pReg = crc_device_info[DeviceNum].pReg;
700 ADI_EXIT_CRITICAL_REGION();
702 crc_ResetRegisters(pDevice);
703 *phDevice = crc_device_info[DeviceNum].hDevice;
705 #if (ADI_CRC_CFG_ENABLE_DMA_SUPPORT == 0) 707 pDevice->pfSubmitBuffer = &crc_ExecuteCoreDrivenOperation;
711 pDevice->pfSubmitBuffer = &crc_ExecuteDmaDrivenOperation;
723 NVIC_EnableIRQ(ADI_CRC_IRQ_ID);
742 ADI_CRC_INFO *pCrcInfo = crc_DeviceInfo(hDevice);
744 if (NULL == pCrcInfo)
751 #if (ADI_CRC_CFG_ENABLE_DMA_SUPPORT != 0) 752 NVIC_DisableIRQ(ADI_CRC_IRQ_ID);
763 pCrcInfo->hDevice = NULL;
787 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
794 else if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
802 pDevice->pReg->CTL |= (BITM_CRC_CTL_BITMIRR);
806 pDevice->pReg->CTL &= (uint32_t)(~(BITM_CRC_CTL_BITMIRR));
830 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
837 else if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
845 pDevice->pReg->CTL |= (BITM_CRC_CTL_BYTMIRR);
849 pDevice->pReg->CTL &= (uint32_t)(~(BITM_CRC_CTL_BYTMIRR));
875 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
882 else if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
890 pDevice->pReg->CTL |= (BITM_CRC_CTL_LSBFIRST);
894 pDevice->pReg->CTL &= ~(BITM_CRC_CTL_LSBFIRST);
918 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
925 else if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
933 pDevice->pReg->CTL |= BITM_CRC_CTL_W16SWP;
937 pDevice->pReg->CTL &= ~BITM_CRC_CTL_W16SWP;
959 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
966 else if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
973 pDevice->pReg->RESULT = CrcSeedVal;
992 uint32_t PolynomialVal)
995 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
1002 else if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
1009 pDevice->pReg->POLY = PolynomialVal;
1044 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
1050 else if (NULL == pDevice)
1054 else if (((pDevice->pReg->CTL & BITM_CRC_CTL_REVID) == 0u) && (NumBits != 0u))
1059 if (!ADI_CRC_DEVICE_IS_IDLE(pDevice))
1066 pDevice->eCrcOpStatus = ADI_CRC_OP_IN_PROGRESS;
1067 result = pDevice->pfSubmitBuffer(pDevice, pCrcBuf, NumBytes, NumBits);
1090 bool *pbCrcInProgress)
1093 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
1096 if (NULL == pDevice)
1104 if ((pDevice)->eCrcOpStatus == ADI_CRC_OP_IN_PROGRESS)
1106 *pbCrcInProgress =
true;
1111 *pbCrcInProgress =
false;
1141 uint32_t *pFinalCrcVal)
1144 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
1147 if (NULL == pDevice)
1155 *pFinalCrcVal = pDevice->pReg->RESULT;
1156 pDevice->pReg->RESULT = seed_value;
1174 uint32_t *pCurrentCrcVal)
1177 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
1180 if (NULL == pDevice)
1187 *pCurrentCrcVal = pDevice->pReg->RESULT;
1220 ADI_CALLBACK pfCallback,
1221 void *
const pCBParam)
1224 ADI_CRC_DEVICE *pDevice = HDL_TO_DEVICE_PTR(hDevice);
1226 ADI_INT_STATUS_ALLOC();
1227 ADI_ENTER_CRITICAL_REGION();
1230 if (NULL == pDevice)
1238 pDevice->pfCallback = pfCallback;
1239 pDevice->pCBParam = pCBParam;
1242 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....