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.

TMS320F28388D: How to change the PDO from the EtherCAT example

Other Parts Discussed in Thread: C2000WARE

Hi everyone,

I am fairly new with EtherCAT and C2000 uC and I have some questions about EtherCAT using the F2838D. I went through the EtherCAT examples in C2000Ware libraries. The f2838x_cpu1_echoback_solution works well.

Now, I would like change the PDO based on my application. Let's say I want to send 2x int_16 and receive 2x int_16 variables from my TwinCAT Master, what is the easiest way to do so?

From my understanding we start with SSC by creating a new project and importing the XML file f2838x_ssc_config that is already containing the PDO. How can I generate the same kind of file? Do I need to manually edit this XML to fit my application?

Also what is the difference between: TI F2838x CPU1 Sample (include Sample Application) and TI F2838x CPU1 Sample ? The "Sample Application" is generated to be imported in ccs?

Thank you

  • Thank you Ranjith

  • Hi,

    You may also leverage developer forum at the ETG member area for any SSC related questions.

    Thanks,

  • Hi Ranjith,

    I created a new application using TI F2838x CPU1 Sample without Sample Application:
     

    and fill the Excel as below:

    It's basically just one input and one output. I generated the Slave file and import it in CCS. I would like to implement APPL_InputMapping() and APPL_OutputMapping() as below:

    void APPL_InputMapping(UINT16* pData)
    {
        uint16_t j = 0;
        uint16_t *pTmpData = (uint16_t *)pData;
        uint16_t data;
    
    
       for (j = 0; j < sTxPDOassign.u16SubIndex0; j++)
       {
          switch (sTxPDOassign.aEntries[j])
          {
          /* TxPDO  */
          case 0x1A00: // 8 bits
              data = Result0x6000;
    
              * (volatile uint16_t *)pTmpData = data;
    
             break;
          }
       }
    }
    
    
    void APPL_OutputMapping(UINT16* pData)
    {
        uint16_t j = 0;
        uint16_t *pTmpData = (uint16_t *)pData;// allow byte processing
        uint16_t data = 0;
        for (j = 0; j < sRxPDOassign.u16SubIndex0; j++)
        {
            switch (sRxPDOassign.aEntries[j])
            {
            /* RxPDO */
            case 0x1600: //byte (8 bits)
                data = (*(volatile uint16_t *)pTmpData);
                Value0x7000 = data;
                break;
            }
        }
    }

    But Result0x6000 and Value0x7000 are not defined.

    If I check F2838x_CPU1_EtherCAT_Slave_1in1out1Objects.h I don't see my variables declaration:

    /*
    * This source file is part of the EtherCAT Slave Stack Code licensed by Beckhoff Automation GmbH & Co KG, 33415 Verl, Germany.
    * The corresponding license agreement applies. This hint shall not be removed.
    */
    
    /**
    * \addtogroup F2838x_CPU1_EtherCAT_Slave_1in1out1 F2838x_CPU1_EtherCAT_Slave_1in1out1
    * @{
    */
    
    /**
    \file F2838x_CPU1_EtherCAT_Slave_1in1out1Objects
    \author ET9300Utilities.ApplicationHandler (Version 1.5.0.0) | EthercatSSC@beckhoff.com
    
    \brief F2838x_CPU1_EtherCAT_Slave_1in1out1 specific objects<br>
    \brief NOTE : This file will be overwritten if a new object dictionary is generated!<br>
    */
    
    #if defined(_F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_) && (_F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_ == 1)
    #define PROTO
    #else
    #define PROTO extern
    #endif
    /******************************************************************************
    *                    Object 0x1C12 : SyncManager 2 assignment
    ******************************************************************************/
    /**
    * \addtogroup 0x1C12 0x1C12 | SyncManager 2 assignment
    * @{
    * \brief Object 0x1C12 (SyncManager 2 assignment) definition
    */
    #ifdef _OBJD_
    /**
    * \brief Entry descriptions<br>
    * 
    * Subindex 0<br>
    */
    OBJCONST TSDOINFOENTRYDESC    OBJMEM asEntryDesc0x1C12[] = {
    { DEFTYPE_UNSIGNED8 , 0x8 , ACCESS_READ }};
    
    /**
    * \brief Object name definition<br>
    * For Subindex 1 to n the syntax 'Subindex XXX' is used
    */
    OBJCONST UCHAR OBJMEM aName0x1C12[] = "SyncManager 2 assignment\000\377";
    #endif //#ifdef _OBJD_
    
    #ifndef _F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_OBJECTS_H_
    /**
    * \brief Object structure
    */
    typedef struct OBJ_STRUCT_PACKED_START {
    UINT16   u16SubIndex0;  /**< \brief Subindex 0 */
    } OBJ_STRUCT_PACKED_END
    TOBJ1C12;
    #endif //#ifndef _F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_OBJECTS_H_
    
    /**
    * \brief Object variable
    */
    PROTO TOBJ1C12 sRxPDOassign
    #if defined(_F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_) && (_F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_ == 1)
    ={0}
    #endif
    ;
    /** @}*/
    
    
    
    /******************************************************************************
    *                    Object 0x1C13 : SyncManager 3 assignment
    ******************************************************************************/
    /**
    * \addtogroup 0x1C13 0x1C13 | SyncManager 3 assignment
    * @{
    * \brief Object 0x1C13 (SyncManager 3 assignment) definition
    */
    #ifdef _OBJD_
    /**
    * \brief Entry descriptions<br>
    * 
    * Subindex 0<br>
    */
    OBJCONST TSDOINFOENTRYDESC    OBJMEM asEntryDesc0x1C13[] = {
    { DEFTYPE_UNSIGNED8 , 0x8 , ACCESS_READ }};
    
    /**
    * \brief Object name definition<br>
    * For Subindex 1 to n the syntax 'Subindex XXX' is used
    */
    OBJCONST UCHAR OBJMEM aName0x1C13[] = "SyncManager 3 assignment\000\377";
    #endif //#ifdef _OBJD_
    
    #ifndef _F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_OBJECTS_H_
    /**
    * \brief Object structure
    */
    typedef struct OBJ_STRUCT_PACKED_START {
    UINT16   u16SubIndex0;  /**< \brief Subindex 0 */
    } OBJ_STRUCT_PACKED_END
    TOBJ1C13;
    #endif //#ifndef _F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_OBJECTS_H_
    
    /**
    * \brief Object variable
    */
    PROTO TOBJ1C13 sTxPDOassign
    #if defined(_F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_) && (_F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_ == 1)
    ={0}
    #endif
    ;
    /** @}*/
    
    
    
    /******************************************************************************
    *                    Object 0xF000 : Modular Device Profile
    ******************************************************************************/
    /**
    * \addtogroup 0xF000 0xF000 | Modular Device Profile
    * @{
    * \brief Object 0xF000 (Modular Device Profile) definition
    */
    #ifdef _OBJD_
    /**
    * \brief Object entry descriptions<br>
    * <br>
    * SubIndex 0<br>
    * SubIndex 1 - Index distance <br>
    * SubIndex 2 - Maximum number of modules <br>
    */
    OBJCONST TSDOINFOENTRYDESC    OBJMEM asEntryDesc0xF000[] = {
    { DEFTYPE_UNSIGNED8 , 0x8 , ACCESS_READ },
    { DEFTYPE_UNSIGNED16 , 0x10 , ACCESS_READ }, /* Subindex1 - Index distance  */
    { DEFTYPE_UNSIGNED16 , 0x10 , ACCESS_READ }}; /* Subindex2 - Maximum number of modules  */
    
    /**
    * \brief Object/Entry names
    */
    OBJCONST UCHAR OBJMEM aName0xF000[] = "Modular Device Profile\000"
    "Index distance \000"
    "Maximum number of modules \000\377";
    #endif //#ifdef _OBJD_
    
    #ifndef _F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_OBJECTS_H_
    /**
    * \brief Object structure
    */
    typedef struct OBJ_STRUCT_PACKED_START {
    UINT16 u16SubIndex0;
    UINT16 IndexDistance; /* Subindex1 - Index distance  */
    UINT16 MaximumNumberOfModules; /* Subindex2 - Maximum number of modules  */
    } OBJ_STRUCT_PACKED_END
    TOBJF000;
    #endif //#ifndef _F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_OBJECTS_H_
    
    /**
    * \brief Object variable
    */
    PROTO TOBJF000 ModularDeviceProfile0xF000
    #if defined(_F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_) && (_F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_ == 1)
    ={2,0x0010,0}
    #endif
    ;
    /** @}*/
    
    
    
    
    
    
    
    #ifdef _OBJD_
    TOBJECT    OBJMEM ApplicationObjDic[] = {
    /* Object 0x1C12 */
    {NULL , NULL ,  0x1C12 , {DEFTYPE_UNSIGNED16 , 0 | (OBJCODE_ARR << 8)} , asEntryDesc0x1C12 , aName0x1C12 , &sRxPDOassign , NULL , NULL , 0x0000 },
    /* Object 0x1C13 */
    {NULL , NULL ,  0x1C13 , {DEFTYPE_UNSIGNED16 , 0 | (OBJCODE_ARR << 8)} , asEntryDesc0x1C13 , aName0x1C13 , &sTxPDOassign , NULL , NULL , 0x0000 },
    /* Object 0xF000 */
    {NULL , NULL ,  0xF000 , {DEFTYPE_RECORD , 2 | (OBJCODE_REC << 8)} , asEntryDesc0xF000 , aName0xF000 , &ModularDeviceProfile0xF000 , NULL , NULL , 0x0000 },
    {NULL,NULL, 0xFFFF, {0, 0}, NULL, NULL, NULL, NULL}};
    #endif    //#ifdef _OBJD_
    #undef PROTO
    
    /** @}*/
    #define _F2838X__CPU1__ETHER_CAT__SLAVE_1IN1OUT1_OBJECTS_H_
    

    Normally it should be directly generated by SSC right?

    As  ask 3 years ago, it would be nice if you had a manual on how to create an application for C2000.

  • Hi,

    The tool should generate the header file. In this case it is not clear why it is not happening. Are you seeing any errors while importing the excel? One question I have is on why the input and output data is of type RECORD if you have only one variable. Shouldn't these be a VARIABLE type?

    Thanks,

  • I used RECORD so I can add more variables in the future.

    I tried several times, it looks like when I am creating a new application, SSC open the Excel and directly parse the file and create the PDO of the empty Excel. It does not wait till I filled the Excel sheet... so that is why none of my variables were declared in the Object.h .

    Now that I fixed that, I can see my variables declared in the Object.h but if I try to compile and get several errors Upside down:

  • Hi,

    Good to know that the SSC tool issue is fixed and you are seeing the generated objects.

    Thanks,