Migrate ENET application from MK60DN256 (Rev 2.x) to MK60DN256Z (Rev 1.x)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Migrate ENET application from MK60DN256 (Rev 2.x) to MK60DN256Z (Rev 1.x)

1,144 Views
Anonymous
Deactivated User

Hello everyone!

I am trying to migrate a simple application using ENET driver from a MK60DN256 (Rev 2.x) to a MK60DN256Z (Rev 1.x).

I came across what I suspect is a known issue about this driver and the Buffer Descriptor: the driver of the DEMO I have got from a generated SDK 2.2 (LWIP ping baremetal) uses the DBSWP functionality from the ENET_ECR register, which is a new functionality added in the 2.x release of the microprocessor I am using.

What I am trying to do now (at the present with little success) is manually disable the DBSWP bit from the ENET_ECR register and swap structure and the endian-ness of _enet_rx_bd_struct.

The migration guide AN4445 says that I have to change the structure from (2.x):

typedef struct
{
   uint16_t length;   /* transfer length */
   uint16_t status;   /* control and status */
   uint8_t *data;      /* buffer address */
} NBUF;

to (1.x):

typedef struct
{
   uint16_t status;   /* control and status */
   uint16_t length;   /* transfer length */
   uint8_t *data;      /* buffer address */
} NBUF;

I also tried to follow some other forum discussions in order to manually swap the endian-ness of the structure content (like bit masks defines).

I am working on it from fiew days now and I think I am missing something (or I am doing something wrong, or something highly discouraged), but I need to find out a solution.

Do you have any suggestions or a driver version already compatible with my micro revision?

In attachment the original version of the driver modules I am working on.

4 Replies

993 Views
mjbcswitzerland
Specialist V

Hi Mattia

You can reference the uTasker project (with integrated TCP/IP stack and real-time Kinetis Ethernet emulation in VisualStudio) on Git Hub. It automatically selects the natural little-endian ENET mode if the chip used support its and operates on all Kinetis parts wit Ethernet or RNDIS over USB.

Below are the defines that need to be controlled so that you quickly solve your present difficulty.

Regards

Mark

#if defined ETHER_DBSWP                                                  // natural little-endian
    typedef struct stKINETIS_FEC_BD
    {
        volatile unsigned short usBDLength;
        volatile unsigned short usBDControl;
        unsigned char *ptrBD_Data;
    #if defined EMAC_ENHANCED                                            // additional fields available in enhanced mode
        volatile unsigned long  ulBDControlEnhanced;
        volatile unsigned short usPayloadCS;                             // only receiver
        volatile unsigned short usRxInfoHeaderProt;                      // only receiver
        volatile unsigned long  ulBDU;
        volatile unsigned long  ul1588_timestamp;
        unsigned long  ulRes[2];
    #endif
    } KINETIS_FEC_BD;

    #define EMPTY_BUFFER         0x8000                                  // RX BD Control bits
    #define RECEIVE_OWNERSHIP_1  0x4000                                  // can be optionally used by software
    #define WRAP_BIT_RX          0x2000
    #define RECEIVE_OWNERSHIP_2  0x1000                                  // can be optionally used by software
    #define LAST_IN_FRAME_RX     0x0800
    #define RECEIVE_MISS         0x0100                                  // received due to promiscuous mode only
    #define RECEIVE_BROADCAST    0x0080                                  // received due to broadcast address
    #define RECEIVE_MULTICAST    0x0040                                  // received due to multicast address
    #define RECEIVE_LENGTH_VIOL  0x0020                                  // receive frame length violation
    #define RECEIVE_NON_OCTET_AL 0x0010                                  // non-octet aligned frame
    #define RECEIVE_CRC_ERROR    0x0004                                  // receive CRC or frame error
    #define OVERRUN_FRAME        0x0002
    #define TRUNCATED_FRAME      0x0001

    // Enhanced
    //
    #define RX_MAC_ERROR         0x80000000
    #define RX_PHY_ERROR         0x04000000
    #define RX_COLLISION         0x02000000
    #define RX_UNICAST           0x01000000
    #define RX_GEN_INTERRUPT     0x00800000
    #define RX_IP_CS_ERROR       0x00000020
    #define RX_PROT_CS_ERROR     0x00000010
    #define RX_VLAN              0x00000004
    #define RX_IPV6              0x00000002
    #define RX_IPV4_FRAG         0x00000001

    #define RX_HEADER_LEN_MASK   0xf800
    #define RX_PROT_TYPE_MASK    0x00ff


    #define READY_TX             0x8000                                  // TX BD Control bits
    #define TRANSMIT_OWNERSHIP_1 0x4000                                  // can be optionally used by software
    #define WRAP_BIT_TX          0x2000
    #define TRANSMIT_OWNERSHIP_2 0x1000                                  // can be optionally used by software
    #define LAST_IN_FRAME_TX     0x0800
    #define TX_CRC               0x0400
    #define TX_ABC               0x0200                                  // append bad CRC - not supported in enhanced mode

    // Enhanced
    //
    #define TX_GENERATE_INT      0x40000000
    #define TX_ADD_TIMESTAMP     0x20000000
    #define TX_INSERT_PROT_CS    0x10000000
    #define TX_INSERT_IP_CS      0x08000000
    #define TX_ERROR_OCCURRED    0x00008000
    #define TX_UNDERFLOW_ERROR   0x00002000
    #define TX_EXCESS_COLLISIONS 0x00001000
    #define TX_FRAME_ERROR       0x00000800
    #define TX_LATE_COLLISION    0x00000400
    #define TX_OVERFLOW_ERROR    0x00000200
    #define TX_TIMESTAMP_ERROR   0x00000100

    #define BD_UPDATE_DONE       0x80000000                              // rx and tx
#else                                                                    // big-endian representation
    typedef struct stKINETIS_FEC_BD
    {
        volatile unsigned short usBDControl;
        volatile unsigned short usBDLength;
        unsigned char *ptrBD_Data;
    #if defined EMAC_ENHANCED                                            // additional fields available in enhanced mode
        volatile unsigned long  ulBDControlEnhanced;
        volatile unsigned short usRxInfoHeaderProt;                      // only receiver
        volatile unsigned short usPayloadCS;                             // only receiver
        volatile unsigned long  ulBDU;
        volatile unsigned long  ul1588_timestamp;
        unsigned long  ulRes[2];
    #endif
    } KINETIS_FEC_BD;

    #define EMPTY_BUFFER         0x0080                                  // RX BD Control bits
    #define RECEIVE_OWNERSHIP_1  0x0040                                  // can be optionally used by software
    #define WRAP_BIT_RX          0x0020
    #define RECEIVE_OWNERSHIP_2  0x0010                                  // can be optionally used by software
    #define LAST_IN_FRAME_RX     0x0008
    #define RECEIVE_MISS         0x0001                                  // received due to promiscuous mode only
    #define RECEIVE_BROADCAST    0x8000                                  // received due to broadcast address
    #define RECEIVE_MULTICAST    0x4000                                  // received due to multicast address
    #define RECEIVE_LENGTH_VIOL  0x2000                                  // receive frame length violation
    #define RECEIVE_NON_OCTET_AL 0x1000                                  // non-octet aligned frame
    #define RECEIVE_CRC_ERROR    0x0400                                  // receive CRC or frame error
    #define OVERRUN_FRAME        0x0200
    #define TRUNCATED_FRAME      0x0100

    // Enhanced
    //
    #define RX_MAC_ERROR         0x00000080
    #define RX_PHY_ERROR         0x00000004
    #define RX_COLLISION         0x00000002
    #define RX_UNICAST           0x00000001
    #define RX_GEN_INTERRUPT     0x00008000
    #define RX_IP_CS_ERROR       0x20000000
    #define RX_PROT_CS_ERROR     0x10000000
    #define RX_VLAN              0x04000000
    #define RX_IPV6              0x02000000
    #define RX_IPV4_FRAG         0x01000000

    #define RX_HEADER_LEN_MASK   0x00f8
    #define RX_PROT_TYPE_MASK    0xff00


    #define READY_TX             0x0080                                  // TX BD Control bits
    #define TRANSMIT_OWNERSHIP_1 0x0040                                  // can be optionally used by software
    #define WRAP_BIT_TX          0x0020
    #define TRANSMIT_OWNERSHIP_2 0x0010                                  // can be optionally used by software
    #define LAST_IN_FRAME_TX     0x0008
    #define TX_CRC               0x0004
    #define TX_ABC               0x0002                                  // append bad CRC - not supported in enhanced mode

    // Enhanced
    //
    #define TX_GENERATE_INT      0x00000040
    #define TX_ADD_TIMESTAMP     0x00000020
    #define TX_INSERT_PROT_CS    0x00000010
    #define TX_INSERT_IP_CS      0x00000008
    #define TX_ERROR_OCCURRED    0x00800000
    #define TX_UNDERFLOW_ERROR   0x00200000
    #define TX_EXCESS_COLLISIONS 0x00100000
    #define TX_FRAME_ERROR       0x00080000
    #define TX_LATE_COLLISION    0x00040000
    #define TX_OVERFLOW_ERROR    0x00020000
    #define TX_TIMESTAMP_ERROR   0x00010000

    #define BD_UPDATE_DONE       0x00000080                              // rx and tx
#endif

993 Views
Anonymous
Deactivated User

Hello Mark,

These are very interesting information, thank you.

I quickly tried to apply them to my project, but  it not seems working anyway.

The changes I applied are:

typedef struct _enet_rx_bd_struct
{
#if 0
    uint16_t length; /*!< Buffer descriptor data length. */
    uint16_t control; /*!< Buffer descriptor control and status. */
    uint8_t *buffer; /*!< Data buffer pointer. */
#else
    uint16_t control; /*!< Buffer descriptor control and status. */
    uint16_t length; /*!< Buffer descriptor data length. */
    uint8_t *buffer; /*!< Data buffer pointer. */
#endif
#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
    uint16_t controlExtend0; /*!< Extend buffer descriptor control0. */
    uint16_t controlExtend1; /*!< Extend buffer descriptor control1. */
    uint16_t payloadCheckSum; /*!< Internal payload checksum. */
    uint8_t headerLength; /*!< Header length. */
    uint8_t protocolTyte; /*!< Protocol type. */
    uint16_t reserved0;
    uint16_t controlExtend2; /*!< Extend buffer descriptor control2. */
    uint32_t timestamp; /*!< Timestamp. */
    uint16_t reserved1;
    uint16_t reserved2;
    uint16_t reserved3;
    uint16_t reserved4;
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
} enet_rx_bd_struct_t;

typedef struct _enet_tx_bd_struct
{
#if 0
   uint16_t length; /*!< Buffer descriptor data length. */
   uint16_t control; /*!< Buffer descriptor control and status. */
   uint8_t *buffer; /*!< Data buffer pointer. */
#else
   uint16_t control; /*!< Buffer descriptor control and status. */
   uint16_t length; /*!< Buffer descriptor data length. */
   uint8_t *buffer; /*!< Data buffer pointer. */
#endif
#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
   uint16_t controlExtend0; /*!< Extend buffer descriptor control0. */
   uint16_t controlExtend1; /*!< Extend buffer descriptor control1. */
   uint16_t reserved0;
   uint16_t reserved1;
   uint16_t reserved2;
   uint16_t controlExtend2; /*!< Extend buffer descriptor control2. */
   uint32_t timestamp; /*!< Timestamp. */
   uint16_t reserved3;
   uint16_t reserved4;
   uint16_t reserved5;
   uint16_t reserved6;
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
} enet_tx_bd_struct_t;
#if 0
#define ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK 0x8000U /*!< Empty bit mask. */
#define ENET_BUFFDESCRIPTOR_RX_SOFTOWNER1_MASK 0x4000U /*!< Software owner one mask. */
#define ENET_BUFFDESCRIPTOR_RX_WRAP_MASK 0x2000U /*!< Next buffer descriptor is the start address. */
#define ENET_BUFFDESCRIPTOR_RX_SOFTOWNER2_Mask 0x1000U /*!< Software owner two mask. */
#define ENET_BUFFDESCRIPTOR_RX_LAST_MASK 0x0800U /*!< Last BD of the frame mask. */
#define ENET_BUFFDESCRIPTOR_RX_MISS_MASK 0x0100U /*!< Received because of the promiscuous mode. */
#define ENET_BUFFDESCRIPTOR_RX_BROADCAST_MASK 0x0080U /*!< Broadcast packet mask. */
#define ENET_BUFFDESCRIPTOR_RX_MULTICAST_MASK 0x0040U /*!< Multicast packet mask. */
#define ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK 0x0020U /*!< Length violation mask. */
#define ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK 0x0010U /*!< Non-octet aligned frame mask. */
#define ENET_BUFFDESCRIPTOR_RX_CRC_MASK 0x0004U /*!< CRC error mask. */
#define ENET_BUFFDESCRIPTOR_RX_OVERRUN_MASK 0x0002U /*!< FIFO overrun mask. */
#define ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK 0x0001U /*!< Frame is truncated mask. */

#define ENET_BUFFDESCRIPTOR_TX_READY_MASK 0x8000U /*!< Ready bit mask. */
#define ENET_BUFFDESCRIPTOR_TX_SOFTOWENER1_MASK 0x4000U /*!< Software owner one mask. */
#define ENET_BUFFDESCRIPTOR_TX_WRAP_MASK 0x2000U /*!< Wrap buffer descriptor mask. */
#define ENET_BUFFDESCRIPTOR_TX_SOFTOWENER2_MASK 0x1000U /*!< Software owner two mask. */
#define ENET_BUFFDESCRIPTOR_TX_LAST_MASK 0x0800U /*!< Last BD of the frame mask. */
#define ENET_BUFFDESCRIPTOR_TX_TRANMITCRC_MASK 0x0400U /*!< Transmit CRC mask. */

#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
#define ENET_BUFFDESCRIPTOR_RX_IPV4_MASK 0x0001U /*!< Ipv4 frame mask. */
#define ENET_BUFFDESCRIPTOR_RX_IPV6_MASK 0x0002U /*!< Ipv6 frame mask. */
#define ENET_BUFFDESCRIPTOR_RX_VLAN_MASK 0x0004U /*!< VLAN frame mask. */
#define ENET_BUFFDESCRIPTOR_RX_PROTOCOLCHECKSUM_MASK 0x0010U /*!< Protocol checksum error mask. */
#define ENET_BUFFDESCRIPTOR_RX_IPHEADCHECKSUM_MASK 0x0020U /*!< IP header checksum error mask. */

#define ENET_BUFFDESCRIPTOR_RX_INTERRUPT_MASK 0x0080U /*!< BD interrupt mask. */
#define ENET_BUFFDESCRIPTOR_RX_UNICAST_MASK 0x0100U /*!< Unicast frame mask. */
#define ENET_BUFFDESCRIPTOR_RX_COLLISION_MASK 0x0200U /*!< BD collision mask. */
#define ENET_BUFFDESCRIPTOR_RX_PHYERR_MASK 0x0400U /*!< PHY error mask. */
#define ENET_BUFFDESCRIPTOR_RX_MACERR_MASK 0x8000U /*!< Mac error mask. */

#define ENET_BUFFDESCRIPTOR_TX_ERR_MASK 0x8000U /*!< Transmit error mask. */
#define ENET_BUFFDESCRIPTOR_TX_UNDERFLOWERR_MASK 0x2000U /*!< Underflow error mask. */
#define ENET_BUFFDESCRIPTOR_TX_EXCCOLLISIONERR_MASK 0x1000U /*!< Excess collision error mask. */
#define ENET_BUFFDESCRIPTOR_TX_FRAMEERR_MASK 0x0800U /*!< Frame error mask. */
#define ENET_BUFFDESCRIPTOR_TX_LATECOLLISIONERR_MASK 0x0400U /*!< Late collision error mask. */
#define ENET_BUFFDESCRIPTOR_TX_OVERFLOWERR_MASK 0x0200U /*!< Overflow error mask. */
#define ENET_BUFFDESCRIPTOR_TX_TIMESTAMPERR_MASK 0x0100U /*!< Timestamp error mask. */

#define ENET_BUFFDESCRIPTOR_TX_INTERRUPT_MASK 0x4000U /*!< Interrupt mask. */
#define ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK 0x2000U /*!< Timestamp flag mask. */
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
#else
#define ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK 0x0080U /*!< Empty bit mask. */
#define ENET_BUFFDESCRIPTOR_RX_SOFTOWNER1_MASK 0x0040U /*!< Software owner one mask. */
#define ENET_BUFFDESCRIPTOR_RX_WRAP_MASK 0x0020U /*!< Next buffer descriptor is the start address. */
#define ENET_BUFFDESCRIPTOR_RX_SOFTOWNER2_Mask 0x0010U /*!< Software owner two mask. */
#define ENET_BUFFDESCRIPTOR_RX_LAST_MASK 0x0008U /*!< Last BD of the frame mask. */
#define ENET_BUFFDESCRIPTOR_RX_MISS_MASK 0x0001U /*!< Received because of the promiscuous mode. */
#define ENET_BUFFDESCRIPTOR_RX_BROADCAST_MASK 0x8000U /*!< Broadcast packet mask. */
#define ENET_BUFFDESCRIPTOR_RX_MULTICAST_MASK 0x4000U /*!< Multicast packet mask. */
#define ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK 0x2000U /*!< Length violation mask. */
#define ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK 0x1000U /*!< Non-octet aligned frame mask. */
#define ENET_BUFFDESCRIPTOR_RX_CRC_MASK 0x0400U /*!< CRC error mask. */
#define ENET_BUFFDESCRIPTOR_RX_OVERRUN_MASK 0x0200U /*!< FIFO overrun mask. */
#define ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK 0x0100U /*!< Frame is truncated mask. */

#define ENET_BUFFDESCRIPTOR_TX_READY_MASK 0x0080U /*!< Ready bit mask. */
#define ENET_BUFFDESCRIPTOR_TX_SOFTOWENER1_MASK 0x0040U /*!< Software owner one mask. */
#define ENET_BUFFDESCRIPTOR_TX_WRAP_MASK 0x0020U /*!< Wrap buffer descriptor mask. */
#define ENET_BUFFDESCRIPTOR_TX_SOFTOWENER2_MASK 0x0010U /*!< Software owner two mask. */
#define ENET_BUFFDESCRIPTOR_TX_LAST_MASK 0x0008U /*!< Last BD of the frame mask. */
#define ENET_BUFFDESCRIPTOR_TX_TRANMITCRC_MASK 0x0004U /*!< Transmit CRC mask. */

#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
#define ENET_BUFFDESCRIPTOR_RX_IPV4_MASK 0x0100U /*!< Ipv4 frame mask. */
#define ENET_BUFFDESCRIPTOR_RX_IPV6_MASK 0x0200U /*!< Ipv6 frame mask. */
#define ENET_BUFFDESCRIPTOR_RX_VLAN_MASK 0x0400U /*!< VLAN frame mask. */
#define ENET_BUFFDESCRIPTOR_RX_PROTOCOLCHECKSUM_MASK 0x1000U /*!< Protocol checksum error mask. */
#define ENET_BUFFDESCRIPTOR_RX_IPHEADCHECKSUM_MASK 0x2000U /*!< IP header checksum error mask. */

#define ENET_BUFFDESCRIPTOR_RX_INTERRUPT_MASK 0x8000U /*!< BD interrupt mask. */
#define ENET_BUFFDESCRIPTOR_RX_UNICAST_MASK 0x0001U /*!< Unicast frame mask. */
#define ENET_BUFFDESCRIPTOR_RX_COLLISION_MASK 0x0002U /*!< BD collision mask. */
#define ENET_BUFFDESCRIPTOR_RX_PHYERR_MASK 0x0004U /*!< PHY error mask. */
#define ENET_BUFFDESCRIPTOR_RX_MACERR_MASK 0x0080U /*!< Mac error mask. */

#define ENET_BUFFDESCRIPTOR_TX_ERR_MASK 0x0080U /*!< Transmit error mask. */
#define ENET_BUFFDESCRIPTOR_TX_UNDERFLOWERR_MASK 0x0020U /*!< Underflow error mask. */
#define ENET_BUFFDESCRIPTOR_TX_EXCCOLLISIONERR_MASK 0x0010U /*!< Excess collision error mask. */
#define ENET_BUFFDESCRIPTOR_TX_FRAMEERR_MASK 0x0008U /*!< Frame error mask. */
#define ENET_BUFFDESCRIPTOR_TX_LATECOLLISIONERR_MASK 0x0004U /*!< Late collision error mask. */
#define ENET_BUFFDESCRIPTOR_TX_OVERFLOWERR_MASK 0x0002U /*!< Overflow error mask. */
#define ENET_BUFFDESCRIPTOR_TX_TIMESTAMPERR_MASK 0x0001U /*!< Timestamp error mask. */

#define ENET_BUFFDESCRIPTOR_TX_INTERRUPT_MASK 0x0040U /*!< Interrupt mask. */
#define ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK 0x0020U /*!< Timestamp flag mask. */
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
#endif

And of course I disabled the DBSWP bit. I cannot figure out what I am missing.

0 Kudos

993 Views
mjbcswitzerland
Specialist V

Mattia

Without looking in more detail I don't know what the problem is but maybe some pointers used by other parts of the code (eg. when constructing the buffer descriptor pointers) need to also be swapped between little and big endian at run time.

If you download the open source uTasker project from GIT hub you can run it in Visual Studio (in both modes) and emulate the complete operation. If you step through the initialisation and compare with your code you may find some additional things required.

Good luck.

Regards

Mark

P.S. If you are a professional and you need a quick solution you can also get help at http://www.utasker.com/support.html

993 Views
Anonymous
Deactivated User

Hello Mark,

Thank you for the support, I finally got through the problem.

I confirm that the problem is on the endian-ness of the buffer descriptor pointers. As I suspected, the whole structure has to work with the reversed endian-ness.

Regards,

Mattia

0 Kudos