void init_DMA0( void ) { // Disable DMA channel 0 DCH0CONCLR = 0x00000080; // Disable DMA channel 0 interrupts IEC1CLR = DMA0_INT_BIT; // Clear interrupt flag IFS1CLR = DMA0_INT_BIT; // Enable DMA master DMACONSET = 0x00008000; // Configure channel 0 DCH0CON = 0x00000003; // Configure starting IRQ - INT0 DCH0ECON = 0x00000310; // Configure channel interrupts / clear all flags DCH0INT = 0x00080000; // Set start/destination addresses DCH0DSA = KVA_TO_PA((void*)&timer_vals); DCH0SSA = KVA_TO_PA((void*)&TMR5); // Source size = 2 bytes (16-bit timer) DCH0SSIZ = 2; // Dest size = 4 bytes DCH0DSIZ = 4; // Transfer size = 2 bytes per event DCH0CSIZ = 2; // Enable DMA channel 0 interrupts IEC1SET = DMA0_INT_BIT; IPC9bits.DMA0IP = 3; IPC9bits.DMA0IS = 0; // Enable channel DCH0CONSET = 0x00000080; }
/********************************************************************* * Function: unsigned int NVMWriteRow(void* address, void* data) * * Description: The largest block of data that can be programmed in * a single operation is 1 row 128 instructions (512 Bytes). The row at * the location pointed to by NVMADDR is programmed with the data buffer * pointed to by NVMSRCADDR. * * PreCondition: The row of data must be pre-loaded into a buffer in RAM. * * Inputs: address: Destination Row address to write. * data: Location of data to write. * * Output: '0' if operation completed successfully. * * Example: NVMWriteRow((void*) 0xBD000000, (void*) 0xA0000000) ********************************************************************/ UINT NVMemWriteRow(void* address, void* data) { unsigned int res; // Set NVMADDR to Address of row t program NVMADDR = KVA_TO_PA((unsigned int)address); // Set NVMSRCADDR to the SRAM data buffer Address NVMSRCADDR = KVA_TO_PA((unsigned int)data); // Unlock and Write Row res = NVMemOperation(NVMOP_ROW_PGM); return res; }
bool Flash_ErasePage(uint32_t address) { PLIB_NVM_FlashAddressToModify(NVM_ID_0, KVA_TO_PA(address)); PerformOperation(PAGE_ERASE_OPERATION); while (!PLIB_NVM_FlashWriteCycleHasCompleted(NVM_ID_0)) { {} } return !PLIB_NVM_WriteOperationHasTerminated(NVM_ID_0); }
bool Flash_WriteWord(uint32_t address, uint32_t data) { PLIB_NVM_FlashAddressToModify(NVM_ID_0, KVA_TO_PA(address)); PLIB_NVM_FlashProvideData(NVM_ID_0, data); PerformOperation(WORD_PROGRAM_OPERATION); while (!PLIB_NVM_FlashWriteCycleHasCompleted(NVM_ID_0)) { {} } return !PLIB_NVM_WriteOperationHasTerminated(NVM_ID_0); }
void Camera_Init(void) { LATJbits.LATJ7 = 0; CNENAbits.CNIEA1 = 1; TRISAbits.TRISA1 = 1; //HSYNC IO Pin CNENJbits.CNIEJ2 = 1; //VSYNC TRISJbits.TRISJ2 = 1; //VSYNC IO Pin CNCONJbits.ON = 1; CNCONAbits.ON = 1; IFS3bits.CNJIF = 0; //Clear intterupt flag IPC31bits.CNJIP = 5; IPC29bits.CNAIP = 7; IEC3bits.CNJIE = 1; IEC3bits.CNAIE = 1; // set the transfer event control: what event is to start the DMA transfer INTCONbits.INT2EP = 1; // rising edge trigger IEC0bits.INT2IE = 1; TRISFbits.TRISF5 = 1; //Input for CLK TRISK = 0xff; //Input for portk DCH0CONbits.CHPRI = 0b11; //Camera DMA channel has highest priority DCH0ECONbits.CHSIRQ = _EXTERNAL_2_VECTOR; DCH0ECONbits.SIRQEN = 1; DCH0DSA = KVA_TO_PA(&GraphicsFrame[0][0][0]); DCH0SSA = KVA_TO_PA((void*)&PORTK); DCH0SSIZ = 1; DCH0DSIZ = (480<<1); DCH0CSIZ = 1; }
/********************************************************************* * Function: unsigned int NVMWriteWord(void* address, unsigned int data) * * Description: The smallest block of data that can be programmed in * a single operation is 1 instruction word (4 Bytes). The word at * the location pointed to by NVMADDR is programmed. * * PreCondition: None * * Inputs: address: Destination address to write. * data: Word to write. * * Output: '0' if operation completed successfully. * * Example: NVMWriteWord((void*) 0xBD000000, 0x12345678) ********************************************************************/ UINT NVMemWriteWord(void* address, UINT data) { UINT res; NVMADDR = KVA_TO_PA((unsigned int)address); // Load data into NVMDATA register NVMDATA = data; // Unlock and Write Word res = NVMemOperation(NVMOP_WORD_PGM); return res; }
/********************************************************************* * Function: unsigned int NVMErasePage(void* address) * * Description: A page erase will erase a single page of program flash, * which equates to 1k instructions (4KBytes). The page to * be erased is selected using NVMADDR. The lower bytes of * the address given by NVMADDR are ignored in page selection. * * PreCondition: None * * Inputs: address: Destination page address to Erase. * * Output: '0' if operation completed successfully. * * Example: NVMemErasePage((void*) 0xBD000000) ********************************************************************/ UINT NVMemErasePage(void* address) { UINT res; // Convert Address to Physical Address NVMADDR = KVA_TO_PA((unsigned int)address); // Unlock and Erase Page res = NVMemOperation(NVMOP_PAGE_ERASE); // Return WRERR state. return res; }
/********************************************************************* * Function: void APP_HostHIDPICkitInitialize(void); * * Overview: Initializes the demo code * * PreCondition: None * * Input: None * * Output: None * ********************************************************************/ void APP_HostHIDPICkitInitialize() { pickit.state = DEVICE_NOT_CONNECTED; pickit.goSEND_OUTPUT_REPORT = false; pickit.inUse = false; pickit.buffer = NULL; // init DMA // Iniialisation DMA UART TX IFS1bits.U2TXIF = 0; IEC1bits.U2TXIE = 0; IEC1CLR= _IEC1_DMA0IE_MASK; // disable DMA channel 0 interrupts IFS1CLR= _IFS1_DMA0IF_MASK; //0x00010000; // clear existing DMA channel 0 interrupt flag DMACONSET= _DMACON_ON_MASK; // enable the DMA controller // program the transfer DCH0SSA=KVA_TO_PA(rspBuffer); // transfer source physical address DCH0DSA=KVA_TO_PA(&U2TXREG); // transfer destination physical address DCH0ECONbits.CHSIRQ = _UART2_TX_IRQ; // IRQ UART2 TX DCH0ECONbits.SIRQEN = 1; // Activation de la commande via interruption DCH0SSIZ=BUFFER_SIZE; // source size 256 bytes DCH0DSIZ=1; // destination size 1 bytes DCH0CSIZ=1; // 1 bytes transferred per event }
/************************************************************************************************** Timer 3 interrupt. Used to generate the horiz and vert sync pulse under control of the state machine ***************************************************************************************************/ void __ISR(_TIMER_3_VECTOR, IPL7SOFT) T3Interrupt(void) { static int *VPtr; static unsigned char AlternateField = 0; // used to count odd/even fields in composite video static unsigned int LineCnt = 1; switch ( VState) { // vertical state machine case SV_PREEQ: // 0 // prepare for the new horizontal line VPtr = VideoBuf; LineCnt = 1; break; case SV_SYNC: // 1 /* if(!vga) { // if the video is composite P_VID_OC_REG = SvSyncT; // start the vertical sync pulse for composite VCount += AlternateField; // in composite video the alternative field has one extra line AlternateField ^= 1; } */ P_VERT_SET_LO; // start the vertical sync pulse for vga break; case SV_POSTEQ: // 2 //if(!vga) P_VID_OC_REG = C_HSYNC_T; // end of the vertical sync pulse for composite P_VERT_SET_HI; // end of the vertical sync pulse for vga break; case SV_LINE: // 3 P_SPI_INPUT = 0; // preload the SPI with 4 zero bytes to pad the start of the video //if(vga) DCH1SSA = KVA_TO_PA((void*) (VPtr)); // update the DMA1 source address (DMA1 is used for VGA data) //else // DCH0SSA = KVA_TO_PA((void*) (VPtr - 1)); // update the DMA0 source address (DMA0 is used for composite data) if(!Display24Lines || LineCnt++ % 3) VPtr += HBuf/32; // move the pointer to the start of the next line DmaChnEnable(1); // arm the DMA transfer break; } if (--VCount == 0) { // count down the number of lines VCount = VC[VState&3]; // set the new count VState = VS[VState&3]; // and advance the state machine } mT3ClearIntFlag(); // clear the interrupt flag }
void CANAssignMemoryBuffer(CAN_MODULE module, void * buffer, UINT sizeInBytes) { /* This function converts the provided * buffer address to a physical address * and stores this address in CxFIFOBA * register. */ CAN_REGISTERS * canRegisters = (CAN_REGISTERS *)canModules[module]; canRegisters->CxFIFOBA = KVA_TO_PA(buffer); }
/**************************************************************************** * Function: _EthAckPacket * * PreCondition: None * * Input: pPkt - buffer/packet to be acknowledged or NULL * pRemList - list to look for done packets and to remove the packets from * pAddList - list were to add the removed packets * ackFnc - function to be called for each acknowledged buffer in turn * fParam - function argument * * Output: ETH_RES_OK - success * ETH_RES_PACKET_QUEUED - there are packets queued * ETH_RES_NO_PACKET - no packets available in the queue * * Side Effects: None * * Overview: This function acknowledges a packet. * The supplied packet has to have been completed otherwise the call will fail. * When pPkt==NULL, all packets with EOWN==0 will be acknowledged. * * Note: None *****************************************************************************/ eEthRes _EthAckPacket(const void* pPkt, sEthDcptList* pRemList, sEthDcptList* pAddList, pEthBuffAck ackFnc, void* fParam) { sEthDNode *pEDcpt; sEthDNode *prev, *next; int nAcks; int pktFound; int buffIx; prev=next=0; nAcks=pktFound=0; for(pEDcpt=pRemList->head; pEDcpt!=0; pEDcpt=next) { if(pEDcpt->hwDcpt.hdr.SOP && (pPkt==0 || pEDcpt->hwDcpt.pEDBuff==(unsigned char*)KVA_TO_PA(pPkt))) { // found the beg of a packet pktFound=1; if(pEDcpt->hwDcpt.hdr.EOWN) { break; // hw not done with it } next=pEDcpt; buffIx=0; do { pEDcpt=next; next=pEDcpt->next; while(pEDcpt->hwDcpt.hdr.EOWN); // shouldn't happen SlAddTail(pAddList, pEDcpt); // ack this node if(ackFnc) { void* pBuff; pBuff=(pEDcpt->hwDcpt.hdr.kv0?PA_TO_KVA0((int)pEDcpt->hwDcpt.pEDBuff):PA_TO_KVA1((int)pEDcpt->hwDcpt.pEDBuff)); (*ackFnc)(pBuff, buffIx++, fParam); // call user's acknowledge } }while(!pEDcpt->hwDcpt.hdr.EOP); nAcks++; // reconstruct the removed list if(prev) { prev->next=next; // prev->next_ed shouldn't matter here! } else { pRemList->head=next; } if(pPkt) { // done, just one packet ack-ed break; // done } } else { prev=pEDcpt; next=pEDcpt->next; } } return nAcks?ETH_RES_OK:(pktFound?ETH_RES_PACKET_QUEUED:ETH_RES_NO_PACKET); }
void DRIVER _DRV_USB_DEVICE_EndpointBDTEntryArm ( DRV_USB_BDT_ENTRY * pBDT, DRV_USB_DEVICE_ENDPOINT_OBJ * endpointObj, USB_DEVICE_IRP_LOCAL * irp, int direction ) { /* pBDT is the pointer to the ping pong BDT entries * for the endpoint and direction In this driver we * dont check for the data toggle while receiving data from * the host. The assumption here is that the host is correct */ /* If the endpoint is stalled, the stall will be cleared */ uint16_t size; DRV_USB_BDT_ENTRY * currentBDTEntry; currentBDTEntry = pBDT + endpointObj->nextPingPong; /* Calculate the size of the transaction */ if(USB_DATA_DIRECTION_DEVICE_TO_HOST == direction) { /* If data is moving from device to host * then enable data toggle syncronization */ currentBDTEntry->byte[0] = 0x08; /* Adjust buffer address for the number of * bytes sent */ currentBDTEntry->word[1] = (uint32_t) (KVA_TO_PA (irp->data + irp->size - irp->nPendingBytes)); if(irp->nPendingBytes == 0) { /* This applies when we need to send a ZLP */ size = 0; } else { size = (irp->nPendingBytes > endpointObj->maxPacketSize) ? endpointObj->maxPacketSize: irp->nPendingBytes; } /* Update the pending bytes only if the * data direction is from device to host. The * pending bytes for the other direction is * updated in the ISR */ irp->nPendingBytes -= size; } else { /* Data is moving from host to device */ currentBDTEntry->byte[0] = 0x0; /* Adjust the buffer address for the number of bytes * received so far */ currentBDTEntry->word[1] = (uint32_t) (KVA_TO_PA (irp->data + irp->nPendingBytes)); size = (irp->size - irp->nPendingBytes > endpointObj->maxPacketSize) ? endpointObj->maxPacketSize : irp->size - irp->nPendingBytes; } /* We set up the data toggle. This will be active * only if DTS is active. Clear the DATA0/1 and * then set it according to the next data toggle * to be used.*/ currentBDTEntry->byte[0] &= 0xBF; currentBDTEntry->byte[0] |= (endpointObj->nextDataToggle << 6); /* Set the size */ currentBDTEntry->shortWord[1] = size; /* Set the UOWN bit */ currentBDTEntry->byte[0] |= 0x80; endpointObj->nextDataToggle ^= 0x1; }
/**************************************************************************** * Function: EthRxBuffersAppend * * PreCondition: EthInit, EthAddDescriptors, EthRxSetBufferSize should have been called. * each buffer supplied should be >= EthRxSetBufferSize(). * * Input: ppBuff - pointer to an array of buffers (could be NULL terminated) to be appended to the receiving process * nBuffs - number of buffers supplied (or 0 if ppBuff is NULL terminated) * rxFlags - flags applied to all RX buffers passed * * Output: ETH_RES_OK for success, * an error code otherwise * * Side Effects: None * * Overview: This function supplies buffers to the receiving process and enables the receiving part of the controller. * As soon as the controller starts receiving data packets these will be stored into memory * at the addresses specified by these buffers. * A received packet can consist of multiple buffers, split across buffers with the SAME size, as specified in the EthRxSetBufferSize(). * Each buffer needs an associated receive descriptor. Therefore, the number of needed * receive descriptors should be available for this function to succeed. * Once a receive operation is scheduled, EthRxPacket() can be called to get the received packet. * * Note: - Not multithreaded safe. Don't call from from both ISR -non ISR code or multiple ISR's! * - This function enables the Ethernet receiving. * - When a packet is split into multiple buffers, all buffers have the same size, set by the EthRxSetBufferSize(). * - The append process continues until a NULL buffer pointer is retrieved or nBuffs buffers are appended. * - Only RX eEthBuffFlags are relevant for this function *****************************************************************************/ eEthRes EthRxBuffersAppend(void* ppBuff[], int nBuffs, eEthBuffFlags rxFlags) { void* pBuff; sEthDNode *pEDcpt; eEthRes res=ETH_RES_OK; sEthDcptList newList={0, 0}; if(nBuffs==0) { nBuffs=0x7fffffff; } for(pBuff=*ppBuff; pBuff!=0 && nBuffs; pBuff=*(++ppBuff), nBuffs--) { pEDcpt=SlRemoveHead(&_EthRxFreeList); if(!pEDcpt) { // we've run out of descriptors... res=ETH_RES_NO_DESCRIPTORS; break; } // ok valid descriptor // pas it to hw, always use linked descriptors pEDcpt->hwDcpt.pEDBuff=(unsigned char*)KVA_TO_PA(pBuff); pEDcpt->hwDcpt.hdr.w=_SDCPT_HDR_NPV_MASK_|_SDCPT_HDR_EOWN_MASK_; // hw owned if(rxFlagsÐ_BUFF_FLAG_RX_STICKY) { pEDcpt->hwDcpt.hdr.sticky=1; } if(rxFlagsÐ_BUFF_FLAG_RX_UNACK) { pEDcpt->hwDcpt.hdr.rx_nack=1; } if(IS_KVA0(pBuff)) { pEDcpt->hwDcpt.hdr.kv0=1; } else if(!IS_KVA(pBuff)) { res=ETH_RES_USPACE_ERR; break; } SlAddTail(&newList, pEDcpt); } if(pBuff && nBuffs) { // failed, still buffers in the descriptors, put back the removed nodes SlAppendTail(&_EthRxFreeList, &newList); return res; } // all's well if(!SlIsEmpty(&newList)) { _EthAppendBusyList(&_EthRxBusyList, &newList, 1); if(ETHRXST==0) { // 1st time reception! ETHRXST=KVA_TO_PA(&_EthRxBusyList.head->hwDcpt); } ETHCON1SET=_ETHCON1_RXEN_MASK; // and we're running! } return ETH_RES_OK; }
void DRIVER _DRV_USB_MAKE_NAME(Initialize) ( const SYS_MODULE_INIT * const init ) { DRV_USB_OBJ * drvObj; DRV_USB_INIT * usbInit; if(gDrvUSBGroup.gDrvUSBObj.inUse == true) { /* Cannot initialize an object that is * already in use. */ SYS_ASSERT(false, "Instance already in use"); return; } usbInit = (DRV_USB_INIT *) init; drvObj = &gDrvUSBGroup.gDrvUSBObj; /* Populate the driver object with * the required data */ drvObj->inUse = true; drvObj->status = SYS_STATUS_BUSY; drvObj->operationMode = usbInit->operationMode; drvObj->pBDT = (DRV_USB_BDT_ENTRY *)(usbInit->endpointTable); /* Turn off USB module */ PLIB_USB_Disable( DRV_USB_PERIPHERAL_ID ); /* Setup the Hardware */ if ( usbInit->stopInIdle ) { PLIB_USB_StopInIdleEnable( DRV_USB_PERIPHERAL_ID ); } else { PLIB_USB_StopInIdleDisable( DRV_USB_PERIPHERAL_ID ); } if ( usbInit->suspendInSleep ) { PLIB_USB_AutoSuspendEnable( DRV_USB_PERIPHERAL_ID ); } else { PLIB_USB_AutoSuspendDisable( DRV_USB_PERIPHERAL_ID ); } /* Setup the USB Module based on the selected * mode */ switch(usbInit->operationMode) { case USB_OPMODE_DEVICE: _DRV_USB_DEVICE_INIT(drvObj, 0); break; case USB_OPMODE_HOST: _DRV_USB_HOST_INIT(drvObj, 0); break; case USB_OPMODE_OTG: break; default: SYS_ASSERT(false, "What mode are you trying?"); break; } /* Clear and enable the interrupts */ _DRV_USB_InterruptSourceClear(DRV_USB_INTERRUPT_SOURCE); _DRV_USB_InterruptSourceEnable(DRV_USB_INTERRUPT_SOURCE); /* Assign the BDT address */ PLIB_USB_BDTBaseAddressSet( DRV_USB_PERIPHERAL_ID , (void *)((uint32_t)KVA_TO_PA(drvObj->pBDT) )); /* Set number of clients to zero */ drvObj->nClients = 0; drvObj->status = SYS_STATUS_READY; return; } /* DRV_USB_Initialize */
void vDMA0_ISR( void ) { #define START_SHORT_LOW 3437 #define START_SHORT_HIGH 3656 #define START_LONG_LOW 4062 #define START_LONG_HIGH 4375 #define BIT_SHORT_LOW 312 #define BIT_SHORT_HIGH 370 #define BIT_LONG_LOW 625 #define BIT_LONG_HIGH 800 #define NUM_KEYS 27 const static unsigned int raw_codes[NUM_KEYS] = { 0x00FD00FF, 0x00FD807F, 0x00FD40BF, 0x00FD20DF, 0x00FDA05F, 0x00FD609F, 0x00FD10EF, 0x00FD906F, 0x00FD50AF, 0x00FD30CF, 0x00FDB04F, 0x00FD708F, 0x00FD08F7, 0x00FD8877, 0x00FD48B7, 0x00FD28D7, 0x00FDA857, 0x00FD6897, 0x00FD18E7, 0x00FD9867, 0x00FD58A7 }; const static unsigned char key_codes[NUM_KEYS] = { 0x11, 0x12, 0x13, 0x21, 0x22, 0x23, 0x31, 0x32, 0x33, 0x41, 0x42, 0x43, 0x51, 0x52, 0x53, 0x61, 0x62, 0x63, 0x71, 0x72, 0x73 }; typedef enum STATE { START, NEW_CODE } STATE; static STATE cState = START; unsigned short pulse_width; static unsigned char code = 0x00; unsigned int raw_code = 0; int i = 0; portBASE_TYPE highPriWoken = pdFALSE; // Clear the event flag DCH0INTCLR = 0x000000FF; IFS1CLR = DMA0_INT_BIT; // Case cState is switch( cState ) { // START case START: // Calculate pulse width pulse_width = timer_vals[1] - timer_vals[0]; // If long pulse if( pulse_width > START_LONG_LOW && pulse_width < START_LONG_HIGH ) { timer_vals[0] = timer_vals[1]; // Configure DMA for NEW_CODE state // Change dest, src, dest size DCH0DSA = KVA_TO_PA((void*)&timer_vals[1]); DCH0SSA = KVA_TO_PA((void*)&TMR5); DCH0DSIZ = 64; // Re-enable DMA channel DCH0CONSET = 0x00000080; // Move to NEW_CODE state cState = NEW_CODE; } // If short pulse else if( pulse_width > START_SHORT_LOW && pulse_width < START_SHORT_HIGH ) { if( code ) { xQueueSendToBackFromISR( queueRemoteCodes, &code, &highPriWoken ); cState = START; } // Re-enable DMA channel DCH0CONSET = 0x00000080; } break; // NEW_CODE case NEW_CODE: // Calculate new code value for( i = 0; i < 32; ++i ) { unsigned short this_time = timer_vals[i + 1] - timer_vals[i]; if( this_time > BIT_LONG_LOW && this_time < BIT_LONG_HIGH ) raw_code = (raw_code << 1) | 0x00000001; else raw_code = raw_code << 1; } // Translate raw code value code = 0x00; for( i = 0; !code && i < NUM_KEYS; ++i ) { if( raw_codes[i] == raw_code ) { code = key_codes[i]; } } // Configure DMA for START state // Change dest, src, dest size DCH0DSA = KVA_TO_PA((void*)&timer_vals); DCH0SSA = KVA_TO_PA((void*)&TMR5); DCH0DSIZ = 4; // Re-enable DMA channel DCH0CONSET = 0x00000080; // Move to START state cState = START; break; } }
void DesCrypt(word32 *key, word32 *iv, byte* out, const byte* in, word32 sz, int dir, int algo, int cryptoalgo) { securityAssociation *sa_p ; bufferDescriptor *bd_p ; const byte *in_p, *in_l ; byte *out_p, *out_l ; volatile securityAssociation sa __attribute__((aligned (8))); volatile bufferDescriptor bd __attribute__((aligned (8))); /* get uncached address */ in_l = in; out_l = out ; sa_p = KVA0_TO_KVA1(&sa) ; bd_p = KVA0_TO_KVA1(&bd) ; in_p = KVA0_TO_KVA1(in_l) ; out_p= KVA0_TO_KVA1(out_l); if(PIC32MZ_IF_RAM(in_p)) XMEMCPY((void *)in_p, (void *)in, sz); XMEMSET((void *)out_p, 0, sz); /* Set up the Security Association */ XMEMSET((byte *)KVA0_TO_KVA1(&sa), 0, sizeof(sa)); sa_p->SA_CTRL.ALGO = algo ; sa_p->SA_CTRL.LNC = 1; sa_p->SA_CTRL.LOADIV = 1; sa_p->SA_CTRL.FB = 1; sa_p->SA_CTRL.ENCTYPE = dir ; /* Encryption/Decryption */ sa_p->SA_CTRL.CRYPTOALGO = cryptoalgo; sa_p->SA_CTRL.KEYSIZE = 1 ; /* KEY is 192 bits */ XMEMCPY((byte *)KVA0_TO_KVA1(&sa.SA_ENCKEY[algo==PIC32_ALGO_TDES ? 2 : 6]), (byte *)key, algo==PIC32_ALGO_TDES ? 24 : 8); XMEMCPY((byte *)KVA0_TO_KVA1(&sa.SA_ENCIV[2]), (byte *)iv, 8); XMEMSET((byte *)KVA0_TO_KVA1(&bd), 0, sizeof(bd)); /* Set up the Buffer Descriptor */ bd_p->BD_CTRL.BUFLEN = sz; bd_p->BD_CTRL.LIFM = 1; bd_p->BD_CTRL.SA_FETCH_EN = 1; bd_p->BD_CTRL.LAST_BD = 1; bd_p->BD_CTRL.PKT_INT_EN = 1; bd_p->BD_CTRL.DESC_EN = 1; bd_p->SA_ADDR = (unsigned int)KVA_TO_PA(&sa) ; /* (unsigned int)sa_p; */ bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in) ; /* (unsigned int)in_p; */ bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out); /* (unsigned int)out_p; */ bd_p->NXTPTR = (unsigned int)KVA_TO_PA(&bd); bd_p->MSGLEN = sz ; /* Fire in the hole! */ CECON = 1 << 6; while (CECON); CEPOLLCON = 10; // 10 SYSCLK delay between BD checks /* Run the engine */ CEBDPADDR = (unsigned int)KVA_TO_PA(&bd) ; /* (unsigned int)bd_p ; */ CEINTEN = 0x07; #if ((__PIC32_FEATURE_SET0 == 'E') && (__PIC32_FEATURE_SET1 == 'C')) // No output swap CECON = 0x27; #else CECON = 0xa7; #endif WAIT_ENGINE ; if((cryptoalgo == PIC32_CRYPTOALGO_CBC) || (cryptoalgo == PIC32_CRYPTOALGO_TCBC)|| (cryptoalgo == PIC32_CRYPTOALGO_RCBC)) { /* set iv for the next call */ if(dir == PIC32_ENCRYPTION) { XMEMCPY((void *)iv, (void*)&(out_p[sz-DES_IVLEN]), DES_IVLEN) ; } else { ByteReverseWords((word32*)iv, (word32 *)&(in_p[sz-DES_IVLEN]), DES_IVLEN); } } #if ((__PIC32_FEATURE_SET0 == 'E') && (__PIC32_FEATURE_SET1 == 'C')) // No output swap ByteReverseWords((word32*)out, (word32 *)KVA0_TO_KVA1(out), sz); #else SYS_DEVCON_DataCacheInvalidate((word32)out, sz); #endif }