CANController *CANController::get(CAN::channel_t channel) { static Mutex _mutex; MutexGuard guard(&_mutex); if (!_controllers[channel]) { uint32_t base; uint32_t periph; void (*handler)(void); switch (channel) { #ifdef HAS_CAN_CHANNEL_0 case CAN::channel_0: base = CAN0_BASE; periph = SYSCTL_PERIPH_CAN0; handler = CAN0IntHandler; break; #endif #ifdef HAS_CAN_CHANNEL_1 case CAN::channel_1: base = CAN1_BASE; periph = SYSCTL_PERIPH_CAN1; handler = CAN1IntHandler; break; #endif #ifdef HAS_CAN_CHANNEL_2 case CAN::channel_2: base = CAN2_BASE; periph = SYSCTL_PERIPH_CAN2; handler = CAN2IntHandler; break; #endif default: while(1); break; } _controllers[channel] = new CANController(channel, periph, base); CANIntRegister(base, handler); } return _controllers[channel]; }
void app_can_init() { /* //27.2.2.34 SysCtlPeripheralPowerOn //Powers on CAN peripheral. //Not used in CAN example. SysCtlPeripheralPowerOn(SYSCTL_PERIPH_CAN0); */ //27.2.2.32 SysCtlPeripheralEnable // GPIO port B and E needs to be enabled so these pins can be used SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); //enable GPIO port B SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); //enable GPIO port E //15.2.3.17 GPIOPinConfigure // Configures pins for use as a CAN device. // Configure the GPIO pin muxing to select CAN0 functions for these pins. // This step selects which alternate function is available for these pins. GPIOPinConfigure(GPIO_PE4_CAN0RX); GPIOPinConfigure(GPIO_PE5_CAN0TX); //15.2.3.20 GPIOPinTypeCAN // Enable the alternate function on the GPIO pins. The above step selects // which alternate function is available. This step actually enables the // alternate function instead of GPIO for these pins. // Configure GPIO Port E pins 4 and 5 to be used as CAN0. GPIOPinTypeCAN(GPIO_PORTE_BASE,GPIO_PIN_4 | GPIO_PIN_5); //15.2.3.27 GPIOPinTypeGPIOOutput // Set GPIO PORTB pins 6 and 7 as output, SW controlled. // CAN_RS=PB6, CAN_Enable=PB7 GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_6 | GPIO_PIN_7); //15.2.3.48 GPIOPinWrite // Writes a "0" to pin PB6 (CAN_RS pin of CAN transceiver TI SN65HVD64). GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_6,0); //enable CAN driver slope control through value of RS resistor. // If a high-level input (> 0.75 VCC) is applied to CAN_RS pin (TI SN65HVD64, pin 8), the circuit enters // a low-current, listen only standby mode during which the driver is switched off and the receiver // remains active. // Uncomment following line (and comment previous line) if a listen-only standby-mode is desired. // // GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_6,GPIO_PIN_6); //CAN driver switched off and CAN receiver active // // // Writes a "1" to pin PB7 CAN_Enable pin of CAN transceiver TI SN65HVD64, enabling the external HW. GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_7,GPIO_PIN_7); //enable CAN transceiver //27.2.2.32 SysCtlPeripheralEnable // The GPIO port and pins have been set up for CAN. The CAN peripheral // must be enabled. SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0); //enable CAN 0 // It takes five clock cycles after the write to enable a peripheral before // the the peripheral is actually enabled. Uncomment following line if needed. // SysCtlDelay(2); //it generates a delay by executing (two times) a 3 instruction cycle loop // 6.2.5.7 CANInit // Initialize the CAN controller CANInit(CAN0_BASE); // 6.2.5.1 CANBitRateSet // Sets the CAN bit timing values to a nominal setting based on a desired bit rate. // If tighter timing requirements or longer network lengths are needed, then the // CANBitTimingSet() function is available for full customization of all of the CAN b // it timing values. CANBitRateSet(CAN0_BASE, SysCtlClockGet(), CAN_BITRATE); // 6.2.5.10 CANIntEnable & 6.2.5.11 CANIntRegister // - Registers an interrupt handler for the CAN controller and // - enable interrupts on the CAN peripheral. // This code uses dynamic allocation of the vector table. If you want static allocation // of interrupt handlers which means the name of the handler is in the vector table of // startup code you must also comment "CANIntRegister(CAN0_BASE, CANIntHandler)". CANIntRegister(CAN0_BASE, CANIntHandler); // needed only using dynamic vectors CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); //18.2.3.2 IntEnable //Enables CAN0 interrupts. IntEnable(INT_CAN0); //6.2.5.5 CANEnable //Enables the CAN controller. CANEnable(CAN0_BASE); }