DMP_INLINE(void) can_RoundRobin(CAN_Bus *can) { CANFrame temp; if (QueueEmpty(can->xmit)) return; io_DisableINT(); if (!(io_In32(can->ioHandle, can->REQ) & (0x01L << (can->round*2)))) { PopBufQueue(can->xmit, (void*)&temp); io_Out32(can->ioHandle, can->TX[can->round].TYPE , (unsigned long)temp.type | ((unsigned long)temp.length << 4)); io_Out32(can->ioHandle, can->TX[can->round].IDR , temp.identifier); io_Out32(can->ioHandle, can->TX[can->round].DATAL, temp.Data.dword[0]); io_Out32(can->ioHandle, can->TX[can->round].DATAH, temp.Data.dword[1]); io_Out32(can->ioHandle, can->REQ, io_In32(can->ioHandle, can->REQ) | (0x01UL << (can->round*2))); can->round++; if (can->round == 3) can->round = 0; } io_RestoreINT(); }
DMP_INLINE(void) can_Reset(CAN_Bus *can) // does not reset ID filter table { int i; unsigned long gcr; if (can == NULL) { err_print((char*)"%s: CAN bus is null.\n", __FUNCTION__); return; } if (can->InUse != 1) { err_print((char*)"%s: CAN bus is not in use.\n", __FUNCTION__); return; } /* Software reset */ io_Out32(can->handle, can->GCR, io_In32(can->handle, can->GCR) | 0x01L); // reset CAN registers while (io_In32(can->handle, can->GCR) & 0x01L); can->state = CAN_STAT_ACTIVE; can->error = CAN_ERROR_NONE; can->ArbiLost_CNT = 0; can->Overrun_CNT = 0; can->TEC = 0; can->REC = 0; for (i = 0; i < 3; i++) memset((void*)&can->TX[i], 0, sizeof(can->TX[i])); memset((void*)&can->RX , 0, sizeof(can->RX) ); can_FlushRxQueue((void *)can); can_FlushTxQueue((void *)can); io_DisableINT(); { io_Out32(can->handle, can->IER, CAN_ALL_INT); } io_RestoreINT(); gcr = io_In32(can->handle, can->GCR); if (can->mode & CAN_ID_BYPASS) gcr |= 0x0004000L; if (can->mode & CAN_POWER_SAVING) gcr |= 0x0100000L; io_Out32(can->handle, can->GCR, gcr |= 0x20382L); // Error retry, Arbitration lost retry, Round Robin // Idenfitier filter enable while (io_In32(can->handle, can->GCR) != gcr); }
static int CAN_ISR(int irq, void *data) { unsigned long isr; CAN_Bus *can = (CAN_Bus *)data; if (((isr = io_In32(can->handle, can->ISR)) & 0x07FFL) != 0x00L) { if (isr & CAN_RXI) { io_DisableINT(); { can->rx_temp.type = (unsigned char)io_In32(can->handle, can->RX.TYPE); can->rx_temp.id = io_In32(can->handle, can->RX.IDR); can->rx_temp.hdata = io_In32(can->handle, can->RX.DATAH); can->rx_temp.ldata = io_In32(can->handle, can->RX.DATAL); PushBufQueue(can->rcvd, (void*)&can->rx_temp); } io_RestoreINT(); io_Out32(can->handle, can->REQ, 0x0100L); // release the received message io_Out32(can->handle, can->ISR, CAN_RXI); } if (isr & CAN_TX0I) { unsigned long stat; stat = io_In32(can->handle, can->TX[0].STAT); if (stat & 0x20L) { can->TX[0].Err_CNT++; can->error = CAN_ERROR_TX0 + (unsigned char)((stat & 0x00070000L) >> 16); if (can->ErrStoreEnable == true) PushQueue(can->err, can->error); if (can->error_handler != NULL) can->error_handler(can); } if ((stat & 0x07L) == 0x05L) can_RoundRobin(can); io_Out32(can->handle, can->ISR, CAN_TX0I); }
static int CAN_ISR(int irq, void *data) { unsigned long isr; CAN_Bus *can = (CAN_Bus *)data; if (((isr = io_In32(can->ioHandle, can->ISR)) & 0x07FFL) != 0x00L) { if (isr & CAN_RXI) { unsigned long temp; CANFrame rx_temp; io_DisableINT(); { temp = io_In32(can->ioHandle, can->RX.TYPE); rx_temp.type = (int)(temp & 0x03UL); rx_temp.length = (int)((temp >> 4) & 0x0FUL); rx_temp.identifier = io_In32(can->ioHandle, can->RX.IDR); rx_temp.Data.dword[0] = io_In32(can->ioHandle, can->RX.DATAL); rx_temp.Data.dword[1] = io_In32(can->ioHandle, can->RX.DATAH); PushBufQueue(can->rcvd, (void*)&rx_temp); } io_RestoreINT(); io_Out32(can->ioHandle, can->REQ, 0x0100UL); // release the received message io_Out32(can->ioHandle, can->ISR, CAN_RXI); } if (isr & CAN_TX0I) { unsigned long stat; stat = io_In32(can->ioHandle, can->TX[0].STAT); if (stat & 0x20UL) { can->LastError = CAN_ERROR_TX0 + (unsigned char)((stat & 0x00070000UL) >> 16); if (can->StoreError) PushQueue(can->Error, can->LastError); }
DMP_INLINE(void) can_RoundRobin(CAN_Bus *can) { if (QueueEmpty(can->xmit)) return; io_DisableINT(); { if (!(io_In32(can->handle, can->REQ) & (0x01L << (round*2)))) { PopBufQueue(can->xmit, (void*)&can->tx_temp); io_Out32(can->handle, can->TX[round].TYPE , (unsigned long)can->tx_temp.type); io_Out32(can->handle, can->TX[round].IDR , can->tx_temp.id); io_Out32(can->handle, can->TX[round].DATAL, can->tx_temp.ldata); io_Out32(can->handle, can->TX[round].DATAH, can->tx_temp.hdata); io_Out32(can->handle, can->REQ, io_In32(can->handle, can->REQ) | (0x01L << (round*2))); round++; if (round == 3) round = 0; } } io_RestoreINT(); }