This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F280025C: Canbus message transferring

Part Number: TMS320F280025C
Other Parts Discussed in Thread: C2000WARE

Tool/software:

Hi guys,
I have a bit of a problem with canbus message transferring exploiting tx interrupt line.

The problem is the following:
I setup the mailbox to be 8 byte long (DLC = 8) in order to transfer some information.
Then, in a simple while loop, I want to send 5-6 consecutive canbus messages each containing different data.

By sniffing the bus using a can analyzer I noticed that the first message is sent with a dlc equal to 8 whereas all the next ones have dlc = 2.
I can't really understand it (I'm pasting down below a screenshot).

I attach a code snippet to let you dive in it.

Let me know if you have any clues, please.
Thanks





Elia

            // WHILE LOOP
            // I receive a serial message and based on it I decide which message I want to send
            
            // WritePkt has as arguments (in order):
            // - canbus message to be sent
            // - serial message from which information is retrieved
            // - length of the canbus message (in order to know which mailbox I should use)
            // - pointer to the serial buffer, in order to be aligned with the information I want to extract
            
            
            while(serial_Rx[ptr_rx] != '\r'){    // indica la fine del messaggio seriale (completo)
                if(serial_Rx[ptr_rx] == '\n'){   // indica l'inizio del sottomessaggio seriale (pacchetto)

                    pkt_id = serial_Rx[ptr_rx+1];
                    switch(pkt_id){

                    case WRITE_MULTIPLE_REGS:
                        WritePkt(WR_multiple, serial_Rx, sizeof(WR_multiple), &ptr_rx);
                        break;

                    case WRITE_PART_NUMBER_1:
                        WritePkt(part_number1, serial_Rx, sizeof(part_number1), &ptr_rx);
                        break;

                    case WRITE_PART_NUMBER_2:
                        WritePkt(part_number2, serial_Rx, sizeof(part_number2), &ptr_rx);
                        break;

                    case WRITE_PART_NUMBER_3:
                        WritePkt(part_number3, serial_Rx, sizeof(part_number3), &ptr_rx);
                        break;

                    case WRITE_PART_NUMBER_4:
                        WritePkt(part_number4, serial_Rx, sizeof(part_number4), &ptr_rx);
                        break;

                    case WRITE_PART_NUMBER_5:
                        WritePkt(part_number5, serial_Rx, sizeof(part_number5), &ptr_rx);
                        break;
                    }
                    DELAY_US(200);
                }
            }
            
            // WRITE PKT
            
            void WritePkt(char *buffer_can, char *buffer_serial, uint16_t size_buffer_can, uint16_t *ptr){

    //uint16_t messageObj;
    // funzione che prende in ingresso i due buffer e restituisce il ptr_rx aggiornato
    // uint16_t CAN_pkt(buffer_can, buffer_serial);
    buffer_can[0] = buffer_serial[*ptr+1];
    buffer_can[1] = buffer_serial[*ptr+2] + ADDR_OFFSET;

    // 6 byte per data
    memcpy(&buffer_can[2], &buffer_serial[*ptr+3], (size_buffer_can/(sizeof(buffer_can[0]))-2));

    // capisco quale tipo di messaggio inviare dalla DLC (ovvero la lunghezza del buffer in ingresso)
    switch(size_buffer_can){
    case DLC_2:
        sendCANMessage(CAN_TX_READ, buffer_can);
        //messageObj = CAN_TX_READ;
        break;

    case DLC_4:
        sendCANMessage(CAN_TX_FEED, buffer_can);
        //messageObj = CAN_TX_FEED;
        break;

    case DLC_8:
        sendCANMessage(CAN_TX_WRITE, buffer_can);
        //messageObj = CAN_TX_WRITE;
        break;
    }

    *ptr += 1 + size_buffer_can/(sizeof(buffer_can[0]));
    //return messageObj;

}
            
            
            
            // ISR TX CANBUS
            
            // Devo riuscire a farlo funzionare!
__interrupt void cana_tx_isr(void){

    dbg.can_tx++;

    while(CanaRegs.CAN_IF1CMD.bit.Busy){}


    // LOCK FEEDER
    if((CanaRegs.CAN_IPEN_21 && (1 << (CAN_TX_LOCK-1))) && (CanaRegs.CAN_INT.bit.INT1ID == CAN_TX_LOCK)){
        GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;

    }
    // WRITE HANDLING
    else if((CanaRegs.CAN_IPEN_21 && (1 << (CAN_TX_WRITE-1))) && (CanaRegs.CAN_INT.bit.INT1ID == CAN_TX_WRITE)){
        GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;

    }
    // READ HANDLING
    else if((CanaRegs.CAN_IPEN_21 && (1 << (CAN_TX_READ-1))) && (CanaRegs.CAN_INT.bit.INT1ID == CAN_TX_READ)){
        GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;

    }
    // FEED HANDLING
    else if((CanaRegs.CAN_IPEN_21 && (1 << (CAN_TX_FEED-1))) && (CanaRegs.CAN_INT.bit.INT1ID == CAN_TX_FEED)){
        GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;

    }

    CanaRegs.CAN_IF1CMD.bit.Control = 1;
    CanaRegs.CAN_IF1CMD.bit.TXRQST = 0;

    //CanaRegs.CAN_IF1CMD.bit.ClrIntPnd = 1;

    CanaRegs.CAN_GLB_INT_CLR.bit.INT1_FLG_CLR = 1;
    PieCtrlRegs.PIEACK.bit.ACK9 = 1;

}
            
            

  • Hi Elia,

    My first suggestion is to inspect register CAN_ES (error register) to see if there are any errors that occurred during transmission.  Unfortunately, it is not straightforward for us to debug a code that this custom and does not use the APIs released in C2000Ware as this involves rewriting and recreating your issues and that takes up a lot of bandwidth. My other suggestion is to look into how our driverlib examples are written in C2000Ware ( I believe i mentioned this to you in my previous post ).

    In the CAN test examples in C2000Ware, you can see that setting up a message object can be accomplished by using API CAN_setupMessafeObject().  With this function call, you can define the 32 message objects (combination of TX and RX).  To send a message object, you can use API CAN_sendMessage() and specify the message object you wanted to send.  You can also use API CAN_readMessage() to read the CAN frame. These APIs set all the register fields that you may not be setting up correctly in your routines so i encourage you first to check these different functions to see how the CAN registers are set up.

    Regards,

    Joseph

  • Hi Joseph,
    thanks for your answer! 
    I'm aware of the driverlib possibilities but I usually prefer to write everything I need by myself (that's the best way to know what I'm doing).
    Driverlib are for sure more efficient and compact but they are hardly catchable if you don't perfectly manage the topic you're dealing with (in my opinion).

    However I'll follow your advice and I'll check driverlib functions to see if something different appears.
    Anyway, the error I'm facing is quite strange and I don't remember anything unsual in the CAN_ES register.

    I'll keep you update on progresses
    Have a nice day!

    Elia

  • Hi Joseph,
    I was able to solve my issue keeping the bitfield configuration.
    By trying different strategies such as surfing the internet, debugging both via code composer and an oscilloscope I could find a way.
    Every time I call the sending function I force the DLC bit to the desired number of bytes to be transmitted on the bus.

    I was biased by previous experience and bad knowledge, where I used to specify the DLC in the setup function only.

    I'll mark your last message as the resolving one.

    Let me thank you fort your time and advices.
    Hope I can help in turn in the future!

    Elia