void cans_init( void ) { MAP_SysCtlPeripheralEnable( SYSCTL_PERIPH_CAN0 ); MAP_CANInit( CAN0_BASE ); CANBitRateSet(CAN0_BASE, LM3S_CAN_CLOCK, 500000); MAP_CANIntEnable( CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS ); MAP_IntEnable(INT_CAN0); MAP_CANEnable(CAN0_BASE); // Configure default catch-all message object can_msg_rx.ulMsgID = 0; can_msg_rx.ulMsgIDMask = 0; can_msg_rx.ulFlags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER; can_msg_rx.ulMsgLen = 8; MAP_CANMessageSet(CAN0_BASE, 1, &can_msg_rx, MSG_OBJ_TYPE_RX); }
void CANController::execute() { while(1) { uint8_t num; while (_usedSwMobs.receive(&num, 0)) { tCANMsgObject *msgobj = &_swmobs[num]; _lastMessageReceivedTimestamp = getTime(); notifyObservers(msgobj); _freeSwMobs.sendToBack(num); } uint32_t timeToWait = sendCyclicCANMessages(); if (timeToWait>100) timeToWait = 100; _usedSwMobs.peek(&num, timeToWait); /* _isrToThreadQueue.peek(&num, timeToWait); uint32_t status = getControlRegister(); // also clears the interrupt if (status & 0xE0) { // bus off, error warning level or error passive MAP_CANDisable(_base); delay_ms(10); MAP_CANInit(_base); setBitrate(_bitrate); enableInterrupts(CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); for (int i=0; i<32; i++) { CANMessageObject *o = getMessageObject(i); o->id = 0; o->mask = 0; o->dlc = 8; o->setRxIntEnabled(i<10); o->setPartOfFIFO(i<9); o->setUseIdFilter(i<10); o->set(CAN::message_type_rx); } MAP_CANEnable(_base); } */ uint32_t status = getControlRegister(); // also clears the interrupt if (status & 0xA0) { // bus off, error warning level or error passive bool s = _silent; _silent = true; MAP_CANDisable(_base); delay_ms(10); MAP_CANInit(_base); setBitrate(_bitrate); enableInterrupts(CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); for (int i=0; i<16; i++) { tCANMsgObject msgobj; msgobj.ulMsgID = 0; msgobj.ulMsgIDMask = 0; msgobj.ulMsgLen = 8; msgobj.pucMsgData = 0; msgobj.ulFlags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER | ((i<15)?MSG_OBJ_FIFO:0); MAP_CANMessageSet(_base, i+1, &msgobj, MSG_OBJ_TYPE_RX); } MAP_CANEnable(_base); delay_ms(10); _silent = s; } } }
void CANController::setup(CAN::bitrate_t bitrate, GPIOPin rxpin, GPIOPin txpin) { rxpin.getPort()->enablePeripheral(); txpin.getPort()->enablePeripheral(); rxpin.configure(GPIOPin::CAN); txpin.configure(GPIOPin::CAN); switch (_channel) { #ifdef HAS_CAN_CHANNEL_0 case CAN::channel_0: rxpin.mapAsCAN0RX(); txpin.mapAsCAN0TX(); break; #endif #ifdef HAS_CAN_CHANNEL_1 case CAN::channel_1: rxpin.mapAsCAN1RX(); txpin.mapAsCAN1TX(); break; #endif #ifdef HAS_CAN_CHANNEL_2 case CAN::channel_2: rxpin.mapAsCAN2RX(); txpin.mapAsCAN2TX(); break; #endif default: while (1) { ; } // something bad happened ... break; } MAP_SysCtlPeripheralEnable(_periph); MAP_CANInit(_base); setBitrate(bitrate); enableInterrupts(CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); for (int i=0; i<16; i++) { /* CANMessageObject *o = getMessageObject(i); o->id = 0; o->mask = 0; o->dlc = 8; o->setRxIntEnabled(i<10); o->setPartOfFIFO(i<9); o->setUseIdFilter(i<10); o->set(CAN::message_type_rx); */ tCANMsgObject msgobj; msgobj.ulMsgID = 0; msgobj.ulMsgIDMask = 0; msgobj.ulMsgLen = 8; msgobj.pucMsgData = 0; msgobj.ulFlags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER | ((i<15)?MSG_OBJ_FIFO:0); MAP_CANMessageSet(_base, i+1, &msgobj, MSG_OBJ_TYPE_RX); } MAP_CANEnable(_base); }