Other Parts Discussed in Thread: SYSCONFIG
//############################################################################# // // FILE: can_ex1_loopback.c // // TITLE: CAN External Loopback Example // //! \addtogroup driver_example_list //! <h1> CAN External Loopback </h1> //! //! This example shows the basic setup of CAN in order to transmit and receive //! messages on the CAN bus. The CAN peripheral is configured to transmit //! messages with a specific CAN ID. A message is then transmitted once per //! second, using a simple delay loop for timing. The message that is sent is //! a 2 byte message that contains an incrementing pattern. //! //! This example sets up the CAN controller in External Loopback test mode. //! Data transmitted is visible on the CANTXA pin and is received internally //! back to the CAN Core. Please refer to details of the External Loopback //! Test Mode in the CAN Chapter in the Technical Reference Manual. Refer //! to [Programming Examples and Debug Strategies for //! the DCAN Module](www.ti.com/lit/SPRACE5) for useful information about //! this example //! //! \b External \b Connections \n //! - None. //! //! \b Watch \b Variables \n //! - msgCount - A counter for the number of successful messages received //! - txMsgData - An array with the data being sent //! - rxMsgData - An array with the data that was received //! // //############################################################################# // // // // C2000Ware v5.03.00.00 // // Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# // // Included Files // #include "driverlib.h" #include "device.h" #include "board.h" // // Defines // #define MSG_DATA_LENGTH 2 #define TX_MSG_OBJ_ID 1 #define RX_MSG_OBJ_ID 2 // // Globals // volatile unsigned long msgCount = 0; uint16_t txMsgData[2], rxMsgData[2]; uint16_t errorFlag = 0; uint16_t rxMsgCount = 0; // // Main // void main(void) { uint16_t txMsgData[2], rxMsgData[2]; // // Initialize device clock and peripherals // Device_init(); // // Initialize GPIO and configure GPIO pins for CANTX/CANRX // Device_initGPIO(); // // Allocated shared peripheral to C28x // SysCtl_allocateSharedPeripheral(SYSCTL_PALLOCATE_CAN_A,0x0U); SysCtl_allocateSharedPeripheral(SYSCTL_PALLOCATE_CAN_B,0x0U); // // Board initialization // Board_init(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // Enable Global Interrupt (INTM) and realtime interrupt (DBGM) // EINT; ERTM; // // Setup send and receive buffers // txMsgData[0] = 0x01; txMsgData[1] = 0x02; *(uint16_t *)rxMsgData = 0; GPIO_togglePin(myBoardLED0_GPIO); DEVICE_DELAY_US(500000); GPIO_togglePin(myBoardLED0_GPIO); GPIO_togglePin(myBoardLED1_GPIO); DEVICE_DELAY_US(500000); GPIO_togglePin(myBoardLED1_GPIO); // // Loop Forever - Send and Receive data continuously // for(;;) { // // Send CAN message data from message object 1 // /* CAN_sendMessage(myCAN0_BASE, 1, MSG_DATA_LENGTH, txMsgData); CAN_readMessage(myCAN0_BASE, RX_MSG_OBJ_ID, rxMsgData); SCI_writeCharNonBlocking(mySCI0_BASE, rxMsgData[0]); DEVICE_DELAY_US(500000); */ } } __interrupt void INT_myCAN0_0_ISR(void) { uint32_t status; GPIO_togglePin(myBoardLED0_GPIO); // // Read the CAN-B interrupt status to find the cause of the interrupt // status = CAN_getInterruptCause(myCAN0_BASE); //SCI_writeCharNonBlocking(mySCI0_BASE, status); // // If the cause is a controller status interrupt, then get the status // /*if(status == CAN_INT_INT0ID_STATUS) { // // Read the controller status. This will return a field of status // error bits that can indicate various errors. Error processing // is not done in this example for simplicity. Refer to the // API documentation for details about the error status bits. // The act of reading this status will clear the interrupt. // status = CAN_getStatus(myCAN0_BASE); // // Check to see if an error occurred. // if(((status & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_MSK) && ((status & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_NONE)) { // // Set a flag to indicate some errors may have occurred. // errorFlag = 1; } //GPIO_togglePin(myBoardLED1_GPIO); }*/ // // Check if the cause is the CAN receive message object 1 // if(status == RX_MSG_OBJ_ID) { // // Get the received message // GPIO_togglePin(myBoardLED1_GPIO); CAN_readMessage(myCAN0_BASE, RX_MSG_OBJ_ID, rxMsgData); // // Getting to this point means that the RX interrupt occurred on // message object 1, and the message RX is complete. Clear the // message object interrupt. // CAN_clearInterruptStatus(myCAN0_BASE, RX_MSG_OBJ_ID); // // Increment a counter to keep track of how many messages have been // received. In a real application this could be used to set flags to // indicate when a message is received. // rxMsgCount++; errorFlag = 0; //GPIO_writePin(myBoardLED0_GPIO, tag); SCI_writeCharNonBlocking(mySCI0_BASE, rxMsgData[0]); CAN_sendMessage(myCAN0_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH, rxMsgData); // // Since the message was received, clear any error flags. // } // // If something unexpected caused the interrupt, this would handle it. // else { // // Spurious interrupt handling can go here. // } // // Clear the global interrupt flag for the CAN interrupt line // // SCI_writeCharNonBlocking(mySCI0_BASE, tag); CAN_clearGlobalInterruptStatus(myCAN0_BASE, CAN_GLOBAL_INT_CANINT0); // // Acknowledge this interrupt located in group 9 // Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9); } __interrupt void INT_myCAN0_1_ISR(void) { } // // End of File //

