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.

TM4C1294NCPDT: preparing a fresh custom board for ethernet applications

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: EK-TM4C1294XL

Hello ,

I want to know, how to prepare a fresh custom board (design based on TM4C1294NCPDT)  to use for networking/Ethernet examples. I mean to say, getting IP from DHCP etc. Does it require any changes on the software side /or changes in the sample example, like(TCP echo example, I've used to test my custom board, here I didn't find definition of EMAC_Init function),which are not needed in case of Launchpad but necessary in case of custom board

I would appreciate any help in this regard.

Thanks

  • Techinspired said:
    here I didn't find definition of EMAC_Init function),which are not needed in case of Launchpad but necessary in case of custom board

    Hi Techinspired,

    Many thanks for the green other thread. :-)

    Can you explain where did you read or discovered above information. What kind of issue are you having with custom PCB not pulling IP address? Can you post a schematic for RJ45 jack section of your PCB? 

  • Hello BP101,

    Thanks for your reply!

    BP101 said:
    Can you explain where did you read or discovered above information.

    Sorry,my mistake ...I meant to say I could not find the definition of EMAC_init() function in TCP echo example. I wanted to check what this function does at EMAC configuration side. I read in its comments.." This function initializes the EMAC driver". So I was checking are there any changes should I need do for a custom board at EMAC configuration.

    BP101 said:
    Can you post a schematic for RJ45 jack section of your PCB? 

    Gateway-0.9.1.sch.pdf

    Secondly I wanted to ask, for any custom board(Design based on TM4C1294NCPDT) ,what changes one need to do on the software side/ sample example codes to get the networking examples working..i.e getting IP address from DHCP etc. I have programmed an arbitrary MAC address (F5-DC-EA-90-10-F2) on my custom board . Apart from this, what other changes do I need to make in the software/sample code, which are not needed in case of a launchpad but are needed in case of a custom board( I don't have knowledge about this...so asking).

    Best Regards,

    Techinspired

  • Via: TIVAWARE_ROOT/driverlib/emac.c

    //*****************************************************************************
    //
    //! Initializes the Ethernet MAC and sets bus-related DMA parameters.
    //!
    //! \param ui32Base is the base address of the Ethernet controller.
    //! \param ui32SysClk is the current system clock frequency in Hertz.
    //! \param ui32BusConfig defines the bus operating mode for the Ethernet MAC
    //! DMA controller.
    //! \param ui32RxBurst is the maximum receive burst size in words.
    //! \param ui32TxBurst is the maximum transmit burst size in words.
    //! \param ui32DescSkipSize is the number of 32-bit words to skip between
    //! two unchained DMA descriptors.  Values in the range 0 to 31 are valid.
    //!
    //! This function sets bus-related parameters for the Ethernet MAC DMA
    //! engines.  It must be called after EMACPHYConfigSet() and called again
    //! after any subsequent call to EMACPHYConfigSet().
    //!
    //! The \e ui32BusConfig parameter is the logical OR of various fields.  The
    //! first sets the DMA channel priority weight:
    //!
    //! - \b EMAC_BCONFIG_DMA_PRIO_WEIGHT_1
    //! - \b EMAC_BCONFIG_DMA_PRIO_WEIGHT_2
    //! - \b EMAC_BCONFIG_DMA_PRIO_WEIGHT_3
    //! - \b EMAC_BCONFIG_DMA_PRIO_WEIGHT_4
    //!
    //! The second field sets the receive and transmit priorities used when
    //! arbitrating between the Rx and Tx DMA.  The priorities are Rx:Tx unless
    //! \b EMAC_BCONFIG_TX_PRIORITY is also specified, in which case they become
    //! Tx:Rx.  The priority provided here is ignored if
    //! \b EMAC_BCONFIG_PRIORITY_FIXED is specified.
    //!
    //! - \b EMAC_BCONFIG_PRIORITY_1_1
    //! - \b EMAC_BCONFIG_PRIORITY_2_1
    //! - \b EMAC_BCONFIG_PRIORITY_3_1
    //! - \b EMAC_BCONFIG_PRIORITY_4_1
    //!
    //! The following additional flags may also be defined:
    //!
    //! - \b EMAC_BCONFIG_TX_PRIORITY indicates that the transmit DMA should be
    //! higher priority in all arbitration for the system-side bus.  If this is not
    //! defined, the receive DMA has higher priority.
    //! - \b EMAC_BCONFIG_ADDR_ALIGNED works in tandem with
    //! \b EMAC_BCONFIG_FIXED_BURST to control address alignment of AHB bursts.
    //! When both flags are specified, all bursts are aligned to the start address
    //! least significant bits.  If \b EMAC_BCONFIG_FIXED_BURST is not specified,
    //! the first burst is unaligned but subsequent bursts are aligned to the
    //! address.
    //! - \b EMAC_BCONFIG_ALT_DESCRIPTORS indicates that the DMA engine should
    //! use the alternate descriptor format as defined in type
    //! \b tEMACDMADescriptor.  If absent, the basic descriptor type is used.
    //! Alternate descriptors are required if using IEEE 1588-2008 advanced
    //! timestamping, VLAN or TCP/UDP/ICMP CRC insertion features.  Note that,
    //! for clarity, emac.h does not contain type definitions for the basic
    //! descriptor type.  Please see the part datasheet for information on basic
    //! descriptor structures.
    //! - \b EMAC_BCONFIG_PRIORITY_FIXED indicates that a fixed priority scheme
    //! should be employed when arbitrating between the transmit and receive DMA
    //! for system-side bus access.  In this case, the receive channel always has
    //! priority unless \b EMAC_BCONFIG_TX_PRIORITY is set, in which case the
    //! transmit channel has priority.  If \b EMAC_BCONFIG_PRIORITY_FIXED is not
    //! specified, a weighted round-robin arbitration scheme is used with the
    //! weighting defined using \b EMAC_BCONFIG_PRIORITY_1_1,
    //! \b EMAC_BCONFIG_PRIORITY_2_1, \b EMAC_BCONFIG_PRIORITY_3_1 or
    //! \b EMAC_BCONFIG_PRIORITY_4_1, and \b EMAC_BCONFIG_TX_PRIORITY.
    //! - \b EMAC_BCONFIG_FIXED_BURST indicates that fixed burst transfers should
    //! be used.
    //! - \b EMAC_BCONFIG_MIXED_BURST indicates that the DMA engine should use
    //! mixed burst types depending on the length of data to be transferred
    //! across the system bus.
    //!
    //! The \e ui32RxBurst and \e ui32TxBurst parameters indicate the maximum
    //! number of words that the relevant DMA should transfer in a single
    //! transaction.  Valid values are 1, 2, 4, 8, 16 and 32.  Any other value
    //! results in undefined behavior.
    //!
    //! The \e ui32DescSkipSize parameter is used when the descriptor lists are
    //! using ring mode (where descriptors are contiguous in memory with the last
    //! descriptor marked with the \b END_OF_RING flag) rather than chained mode
    //! (where each descriptor includes a field that points to the next descriptor
    //! in the list).  In ring mode, the hardware uses the \e ui32DescSkipSize to
    //! skip past any application-defined fields after the end of the hardware-
    //! defined descriptor fields.  The parameter value indicates the number of 
    //! 32-bit words to skip after the last field of the hardware-defined 
    //! descriptor to get to the first field of the next descriptor.  When using 
    //! arrays of either the \b tEMACDMADescriptor or \b tEMACAltDMADescriptor 
    //! types defined for this driver, \e ui32DescSkipSize must be set to 1 to skip
    //!  the \e pvNext pointer added to the end of each of these structures.  
    //! Applications may modify these structure definitions to include their own
    //! application-specific data and modify \e ui32DescSkipSize appropriately if
    //! desired.
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    EMACInit(uint32_t ui32Base, uint32_t ui32SysClk, uint32_t ui32BusConfig,
             uint32_t ui32RxBurst, uint32_t ui32TxBurst, uint32_t ui32DescSkipSize)
    {
        uint32_t ui32Val, ui32Div;
    
        //
        // Parameter sanity checks.
        //
        ASSERT(ui32DescSkipSize < 32);
        ASSERT(ui32TxBurst < (32 * 8));
        ASSERT(ui32RxBurst < (32 * 8));
    
        //
        // Make sure that the DMA software reset is clear before continuing.
        //
        while(HWREG(EMAC0_BASE + EMAC_O_DMABUSMOD) & EMAC_DMABUSMOD_SWR)
        {
        }
    
        //
        // Set common flags.  Note that this driver assumes we are always using
        // 8 word descriptors so we need to OR in EMAC_DMABUSMOD_ATDS here.
        //
        ui32Val = (ui32BusConfig | (ui32DescSkipSize << EMAC_DMABUSMOD_DSL_S) |
                   EMAC_DMABUSMOD_ATDS);
    
        //
        // Do we need to use the 8X burst length multiplier?
        //
        if((ui32TxBurst > 32) || (ui32RxBurst > 32))
        {
            //
            // Divide both burst lengths by 8 and set the 8X burst length
            // multiplier.
            //
            ui32Val |= EMAC_DMABUSMOD_8XPBL;
            ui32TxBurst >>= 3;
            ui32RxBurst >>= 3;
    
            //
            // Sanity check - neither burst length should have become zero.  If
            // they did, this indicates that the values passed are invalid.
            //
            ASSERT(ui32RxBurst);
            ASSERT(ui32TxBurst);
        }
    
        //
        // Are the receive and transmit burst lengths the same?
        //
        if(ui32RxBurst == ui32TxBurst)
        {
            //
            // Yes - set up to use a single burst length.
            //
            ui32Val |= (ui32TxBurst << EMAC_DMABUSMOD_PBL_S);
        }
        else
        {
            //
            // No - we need to use separate burst lengths for each.
            //
            ui32Val |= (EMAC_DMABUSMOD_USP |
                        (ui32TxBurst << EMAC_DMABUSMOD_PBL_S) |
                        (ui32RxBurst << EMAC_DMABUSMOD_RPBL_S));
        }
    
        //
        // Finally, write the bus mode register.
        //
        HWREG(ui32Base + EMAC_O_DMABUSMOD) = ui32Val;
    
        //
        // Default the MII CSR clock divider based on the fastest system clock.
        //
        ui32Div = g_pi16MIIClockDiv[NUM_CLOCK_DIVISORS - 1].ui32Divisor;
    
        //
        // Find the MII CSR clock divider to use based on the current system clock.
        //
        for(ui32Val = 0; ui32Val < NUM_CLOCK_DIVISORS; ui32Val++)
        {
            if(ui32SysClk <= g_pi16MIIClockDiv[ui32Val].ui32SysClockMax)
            {
                ui32Div = g_pi16MIIClockDiv[ui32Val].ui32Divisor;
                break;
            }
        }
    
        //
        // Set the MII CSR clock speed.
        //
        HWREG(ui32Base + EMAC_O_MIIADDR) = ((HWREG(ui32Base + EMAC_O_MIIADDR) &
                                             ~EMAC_MIIADDR_CR_M) | ui32Div);
    
        //
        // Disable all the MMC interrupts as these are enabled by default at reset.
        //
        HWREG(ui32Base + EMAC_O_MMCRXIM) = 0xFFFFFFFF;
        HWREG(ui32Base + EMAC_O_MMCTXIM) = 0xFFFFFFFF;
    }

    cb_1's wise words (weathering the test of time, too!)  are of definite value here; the learning experience of loading and linking the whole Tivaware library will teach you most of what you need to know. Get into the habit of breaking-your-researches-down into small, manageable, testable parts.

    Focus on the small bits first. They will add up into a beautiful picture. That being said, have you attempted to get an example working with a dev-board first... before worrying about the old "fraught with dangers, for thar be dragons here" road of custom-board-development? There is a great balance which must be found; changes will be necessary depending on the hardware (custom board) designer's.. Design.

    Without knowing how you learn best, I would like to make a general recommendation - Get yourself a printout of the custom board schematic, and label the tracks for each port and pin to the ETH section. Breadcrumbs to think about. 

    Break things down, 'keep it simple, stupid,' and venture on. Let us all know what else you may require.

  • Hello BP101.

    BP101 said:
    Can you post a schematic for RJ45 jack section of your PCB? 

    Please find attached schematic of custom board for Ethernet. Please let me know what else I'm missing here?

    5773.Gateway-0.9.1.sch.pdf

    Thanks and Regards,

    Techinspired

  • Schematic has Ethernet U5 (TRJ19111DNL) as a transformer with RJ45 jack built into it? Might work or not relative to the Bias resistors and capacitors values in the circuit.

    EK-TM4C1294XL schematic suggest to use:
    HX1188FNL or HX1198FNL.
    HX1198FNL preferred for best Ethernet performance.
  • Techinspired said:
    I could not find the definition of EMAC_init()

    This probably isn't what you want, but its in your TivaWare install directory /packages/ti/drivers/EMAC.c

    void EMAC_init(void)
    {
        /*
         *  Allow only the first initialization to do anything.
         *  The next ones are nops.
         */
        if (EMAC_count >= 0) {
            return;
        }
    
        /* Call each driver's init function */
        for (EMAC_count = 0; EMAC_config[EMAC_count].fxnTablePtr != NULL;
             EMAC_count++) {
            EMAC_config[EMAC_count].fxnTablePtr->emacInit(EMAC_count);
        }
    
        return;
    }

    The function pointer goes to EMACSnow_init() which doesn't do any hardware configuration.

    Side question, is this function trying to say EMAC Snow (burrr!) or EMACS now (vim > emacs)?