===== CAN ping-pong ===== //Requirements: [HW] 2 x [[en:hardware:arm-can:controller]]// [{{ :images:projects:can_ping_pong:can_ping_pong_animation.gif|RGB LEDs flashing on frame arrival}}] The following program demonstrates the usage of CAN messaging on ARM-CAN controllers. Both controller have the same code. Whenever the button is pressed, a CAN message carrying a ping number is sent. If the message is received by the other node, it lights up it's red LED with intensity relative to the ping number and waits for 200 ms. After that it turns the LED off and sends the similar packet with decreased ping number to the controller which sent it out at first place. Messages are exchanged until the ping count reaches zero. ~~CL~~ ===== can_ping_pong.c ===== //***************************************************************************** // // CAN ping-pong demo // // This program does not use CAN interrupts. // // Copyright (c) 2009 TUT Department of Mechatronics // //***************************************************************************** #include #include #include #include #include #include #include #include #include //***************************************************************************** // // Configuration. // //***************************************************************************** #define CAN_BITRATE 250000 #define CAN_MSG_ID 0x01 #define CAN_MSG_OBJ_RX 1 #define CAN_MSG_OBJ_TX 2 #define PING_START_COUNT 15 #define PING_PERIOD 200 //***************************************************************************** // // Ping command. Send CAN TX frame. // //***************************************************************************** void Ping(unsigned long ulCount) { tCANMsgObject psPingMsg; // // Setup ping message object. // psPingMsg.ulMsgID = CAN_MSG_ID; psPingMsg.ulFlags = MSG_OBJ_NO_FLAGS; psPingMsg.ulMsgLen = 4; psPingMsg.pucMsgData = (unsigned char *)&ulCount; // // Set message. // CANMessageSet(CAN0_BASE, CAN_MSG_OBJ_TX, &psPingMsg, MSG_OBJ_TYPE_TX); } //***************************************************************************** // // Main function. // //***************************************************************************** int main(void) { tCANMsgObject psEchoMsg; tBoolean bButtonState, bButtonOldState = false; unsigned char pucRxData[8]; unsigned long ulPingCount = 0; // // Set the clocking to run from the PLL at 50MHz // SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ); // // Enable peripherals. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0); // // Configuring. // DeviceConfigure(); RGBLEDConfigure(); // // Configure CAN pins. // GPIOPinTypeCAN(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Enable the CAN controller. // CANInit(CAN0_BASE); CANBitRateSet(CAN0_BASE, SysCtlClockGet(), CAN_BITRATE); CANEnable(CAN0_BASE); // // Create echo message object. // psEchoMsg.ulMsgID = CAN_MSG_ID; psEchoMsg.ulMsgIDMask = 0xFF; psEchoMsg.ulFlags = MSG_OBJ_NO_FLAGS; psEchoMsg.pucMsgData = pucRxData; // // Set message object. // CANMessageSet(CAN0_BASE, CAN_MSG_OBJ_RX, &psEchoMsg, MSG_OBJ_TYPE_RX); // // Enable processor interrupts. // IntMasterEnable(); // // Loop forever. // while (1) { // // Get button state. // bButtonState = ButtonIsPressed(); // // Button has been pressed down ? // if (bButtonState && !bButtonOldState) { // // First ping. // Ping(PING_START_COUNT); // // Reset countdown. // CountDownReset(); } // // Remember last button state. // bButtonOldState = bButtonState; // // CAN message received ? // if (CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT) & (1 << (CAN_MSG_OBJ_RX - 1))) { // // Get the message. // CANMessageGet(CAN0_BASE, CAN_MSG_OBJ_RX, &psEchoMsg, true); // // Check message length. // if (psEchoMsg.ulMsgLen == 4) { // // Get ping count and decrease it. // ulPingCount = *((unsigned long *)psEchoMsg.pucMsgData); // // Light up RGB LED. // RGBLEDSetRed(ulPingCount * 255 / PING_START_COUNT); // // Start countdown timer. // CountDownStartMS(PING_PERIOD); } } // // Countdown ended ? // if (CountDownHasEnded()) { // // Turn off the LED. // RGBLEDSetRed(0); // // Send ping if any bounces left. // if (ulPingCount > 0) { // // Ping with decreased count. // Ping(--ulPingCount); } // // Reset countdown. // CountDownReset(); } } }