void dma_init(void) { /* DMA 1 (RIF Tx), 2 (RIF Rx) allocated to DSP, all others to ARM */ writew(0x000c, DMA_REG(ALLOC_CONFIG)); }
CO_ReturnError_t CO_CANmodule_init( CO_CANmodule_t *CANmodule, uint16_t CANbaseAddress, CO_CANrx_t rxArray[], uint16_t rxSize, CO_CANtx_t txArray[], uint16_t txSize, uint16_t CANbitRate) { uint16_t i; volatile uint16_t *pRXF; uint16_t DMArxBaseAddress; uint16_t DMAtxBaseAddress; __eds__ CO_CANrxMsg_t *CANmsgBuff; uint8_t CANmsgBuffSize; uint16_t CANmsgBuffDMAoffset; #if defined(__HAS_EDS__) uint16_t CANmsgBuffDMApage; #endif /* verify arguments */ if(CANmodule==NULL || rxArray==NULL || txArray==NULL){ return CO_ERROR_ILLEGAL_ARGUMENT; } /* Get global addresses for CAN module 1 or 2. */ if(CANbaseAddress == ADDR_CAN1) { DMArxBaseAddress = CO_CAN1_DMA0; DMAtxBaseAddress = CO_CAN1_DMA1; CANmsgBuff = &CO_CAN1msg[0]; CANmsgBuffSize = CO_CAN1msgBuffSize; CANmsgBuffDMAoffset = __builtin_dmaoffset(&CO_CAN1msg[0]); #if defined(__HAS_EDS__) CANmsgBuffDMApage = __builtin_dmapage(&CO_CAN1msg[0]); #endif } #if CO_CAN2msgBuffSize > 0 else if(CANbaseAddress == ADDR_CAN2) { DMArxBaseAddress = CO_CAN2_DMA0; DMAtxBaseAddress = CO_CAN2_DMA1; CANmsgBuff = &CO_CAN2msg[0]; CANmsgBuffSize = CO_CAN2msgBuffSize; CANmsgBuffDMAoffset = __builtin_dmaoffset(&CO_CAN2msg[0]); #if defined(__HAS_EDS__) CANmsgBuffDMApage = __builtin_dmapage(&CO_CAN2msg[0]); #endif } #endif else { return CO_ERROR_ILLEGAL_ARGUMENT; } /* Configure object variables */ CANmodule->CANbaseAddress = CANbaseAddress; CANmodule->CANmsgBuff = CANmsgBuff; CANmodule->rxArray = rxArray; CANmodule->rxSize = rxSize; CANmodule->txArray = txArray; CANmodule->txSize = txSize; CANmodule->useCANrxFilters = (rxSize <= 16U) ? true : false; CANmodule->bufferInhibitFlag = false; CANmodule->firstCANtxMessage = true; CANmodule->CANtxCount = 0U; CANmodule->errOld = 0U; CANmodule->em = NULL; for(i=0U; i<rxSize; i++){ rxArray[i].ident = 0U; rxArray[i].pFunct = NULL; } for(i=0U; i<txSize; i++){ txArray[i].bufferFull = false; } /* Configure control registers */ CAN_REG(CANbaseAddress, C_CTRL1) = 0x0400; CAN_REG(CANbaseAddress, C_CTRL2) = 0x0000; /* Configure CAN timing */ switch(CANbitRate){ case 10: i=0; break; case 20: i=1; break; case 50: i=2; break; default: case 125: i=3; break; case 250: i=4; break; case 500: i=5; break; case 800: i=6; break; case 1000: i=7; break; } if(CO_CANbitRateData[i].scale == 2) CAN_REG(CANbaseAddress, C_CTRL1) |= 0x0800; CAN_REG(CANbaseAddress, C_CFG1) = (CO_CANbitRateData[i].SJW - 1) << 6 | (CO_CANbitRateData[i].BRP - 1); CAN_REG(CANbaseAddress, C_CFG2) = ((uint16_t)(CO_CANbitRateData[i].phSeg2 - 1)) << 8 | 0x0080 | (CO_CANbitRateData[i].phSeg1 - 1) << 3 | (CO_CANbitRateData[i].PROP - 1); /* setup RX and TX control registers */ CAN_REG(CANbaseAddress, C_CTRL1) &= 0xFFFE; /* WIN = 0 - use buffer registers */ CAN_REG(CANbaseAddress, C_RXFUL1) = 0x0000; CAN_REG(CANbaseAddress, C_RXFUL2) = 0x0000; CAN_REG(CANbaseAddress, C_RXOVF1) = 0x0000; CAN_REG(CANbaseAddress, C_RXOVF2) = 0x0000; CAN_REG(CANbaseAddress, C_TR01CON) = 0x0080; /* use one buffer for transmission */ CAN_REG(CANbaseAddress, C_TR23CON) = 0x0000; CAN_REG(CANbaseAddress, C_TR45CON) = 0x0000; CAN_REG(CANbaseAddress, C_TR67CON) = 0x0000; /* CAN module hardware filters */ CAN_REG(CANbaseAddress, C_CTRL1) |= 0x0001; /* WIN = 1 - use filter registers */ CAN_REG(CANbaseAddress, C_FEN1) = 0xFFFF; /* enable all 16 filters */ CAN_REG(CANbaseAddress, C_FMSKSEL1) = 0x0000; /* all filters are using mask 0 */ CAN_REG(CANbaseAddress, C_FMSKSEL2) = 0x0000; CAN_REG(CANbaseAddress, C_BUFPNT1) = 0xFFFF; /* use FIFO for all filters */ CAN_REG(CANbaseAddress, C_BUFPNT2) = 0xFFFF; CAN_REG(CANbaseAddress, C_BUFPNT3) = 0xFFFF; CAN_REG(CANbaseAddress, C_BUFPNT4) = 0xFFFF; /* set all filters to 0 */ pRXF = &CAN_REG(CANbaseAddress, C_RXF0SID); for(i=0; i<16; i++){ *pRXF = 0x0000; pRXF += 2; } if(CANmodule->useCANrxFilters){ /* CAN module filters are used, they will be configured with */ /* CO_CANrxBufferInit() functions, called by separate CANopen */ /* init functions. */ /* All mask bits are 1, so received message must match filter */ CAN_REG(CANbaseAddress, C_RXM0SID) = 0xFFE8; CAN_REG(CANbaseAddress, C_RXM1SID) = 0xFFE8; CAN_REG(CANbaseAddress, C_RXM2SID) = 0xFFE8; } else{ /* CAN module filters are not used, all messages with standard 11-bit */ /* identifier will be received */ /* Set masks so, that all messages with standard identifier are accepted */ CAN_REG(CANbaseAddress, C_RXM0SID) = 0x0008; CAN_REG(CANbaseAddress, C_RXM1SID) = 0x0008; CAN_REG(CANbaseAddress, C_RXM2SID) = 0x0008; } /* WIN = 0 - use buffer registers for default */ CAN_REG(CANbaseAddress, C_CTRL1) &= 0xFFFE; /* Configure DMA controller */ /* Set size of buffer in DMA RAM (FIFO Area Starts with Tx/Rx buffer TRB1 (FSA = 1)) */ /* Use maximum 16 buffers, because we have 16-bit system. */ if (CANmsgBuffSize >= 16) { CAN_REG(CANbaseAddress, C_FCTRL) = 0x8001; CANmodule->CANmsgBuffSize = 16; } else if(CANmsgBuffSize >= 12) { CAN_REG(CANbaseAddress, C_FCTRL) = 0x6001; CANmodule->CANmsgBuffSize = 12; } else if(CANmsgBuffSize >= 8) { CAN_REG(CANbaseAddress, C_FCTRL) = 0x4001; CANmodule->CANmsgBuffSize = 8; } else if(CANmsgBuffSize >= 6) { CAN_REG(CANbaseAddress, C_FCTRL) = 0x2001; CANmodule->CANmsgBuffSize = 6; } else if(CANmsgBuffSize >= 4) { CAN_REG(CANbaseAddress, C_FCTRL) = 0x0001; CANmodule->CANmsgBuffSize = 4; } else { return CO_ERROR_ILLEGAL_ARGUMENT; } /* DMA chanel initialization for ECAN reception */ DMA_REG(DMArxBaseAddress, DMA_CON) = 0x0020; DMA_REG(DMArxBaseAddress, DMA_PAD) = (volatile uint16_t) &CAN_REG(CANbaseAddress, C_RXD); DMA_REG(DMArxBaseAddress, DMA_CNT) = 7; DMA_REG(DMArxBaseAddress, DMA_REQ) = (CANbaseAddress==ADDR_CAN1) ? 34 : 55; #ifndef __HAS_EDS__ DMA_REG(DMArxBaseAddress, DMA_STA) = CANmsgBuffDMAoffset; #else DMA_REG(DMArxBaseAddress, DMA_STAL) = CANmsgBuffDMAoffset; DMA_REG(DMArxBaseAddress, DMA_STAH) = CANmsgBuffDMApage; #endif DMA_REG(DMArxBaseAddress, DMA_CON) = 0x8020; /* DMA chanel initialization for ECAN transmission */ DMA_REG(DMAtxBaseAddress, DMA_CON) = 0x2020; DMA_REG(DMAtxBaseAddress, DMA_PAD) = (volatile uint16_t) &CAN_REG(CANbaseAddress, C_TXD); DMA_REG(DMAtxBaseAddress, DMA_CNT) = 7; DMA_REG(DMAtxBaseAddress, DMA_REQ) = (CANbaseAddress==ADDR_CAN1) ? 70 : 71; #ifndef __HAS_EDS__ DMA_REG(DMAtxBaseAddress, DMA_STA) = CANmsgBuffDMAoffset; #else DMA_REG(DMAtxBaseAddress, DMA_STAL) = CANmsgBuffDMAoffset; DMA_REG(DMAtxBaseAddress, DMA_STAH) = CANmsgBuffDMApage; #endif DMA_REG(DMAtxBaseAddress, DMA_CON) = 0xA020; /* CAN interrupt registers */ /* clear interrupt flags */ CAN_REG(CANbaseAddress, C_INTF) = 0x0000; /* enable receive and transmit interrupt */ CAN_REG(CANbaseAddress, C_INTE) = 0x0003; /* CAN interrupt (combined) must be configured by application */ return CO_ERROR_NO; }