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.

OMAPL137 EMAC Module MACADDRHI read only

Other Parts Discussed in Thread: OMAP-L137

Hello,

I'm trying to configure the Ethernet  interface on an OMAP-L137 evalutation board, but I cannot modify the content of the MACADDRHI register of the emac Module to set the MAC addresses of the device. Here is the code I use to initialize the Emac Module up to the initialization of the mac addresses :

void mdioInit() {
//    setting the divider of the MDIO to reach a 1MHz clock (from 50MHz clock)
    CSL_FINS(mdioRegs->CONTROL, MDIO_CONTROL_CLKDIV, 0x20);
    
//    Enable the state machine
    CSL_FINST(mdioRegs->CONTROL, MDIO_CONTROL_ENABLE, YES);

}

void emacModuleInit() {
//    Select MII mode

// Open Permissions to SYSCFG Registers
    _call_swi(ARM_PRIV_MODE_KEY);
    CSL_FINS(sysRegs->KICK0R, SYSCFG_KICK0R_KICK0, KICK0_KEY);
    CSL_FINS(sysRegs->KICK1R, SYSCFG_KICK1R_KICK1, KICK1_KEY);


//    1. If enabled, clear the device interrupt enable bits in the EMAC control module
//        interrupt control registers CnRXTHRESHEN, CnRXEN, CnTXEN, and CnMISCEN.

    CSL_FINS(emacCtlRegs->SOFTRESET, ECTL_SOFTRESET_RESET, 1);

//    2. Clear the MAC control register (MACCONTROL), receive control register
//        (RXCONTROL), and transmit control register (TXCONTROL) (not necessary
//        immediately after reset).

    CSL_FINST(emacRegs->SOFTRESET, EMAC_SOFTRESET_SOFTRESET, RESET);

    while (CSL_FEXT(emacRegs->SOFTRESET, EMAC_SOFTRESET_SOFTRESET) != 0)
        ;

    delay(100 * infiniteTimerBitsPerMicroSecond);

    mdioInit();

    UINT16 tmpReg;

    UINT64 endTimeout = readInfiniteTimer() + 3 * infiniteTimerBitsPerSecond;

    do {
        accessPHYregister(3, 1, FALSE, &tmpReg);
        delay(100 * infiniteTimerBitsPerMicroSecond);
    } while ((tmpReg & 0x4) == 0 && (endTimeout > readInfiniteTimer()));

    if ((tmpReg & 0x4) == 0) {
        return;
    }

    emacRegs->MACCONTROL = 0;
    emacRegs->RXCONTROL = 0;
    emacRegs->TXCONTROL = 0;

//    3. Initialize all 16 header descriptor pointer registers (RXnHDP and TXnHDP) to 0.

    emacRegs->RX0HDP = 0;
    emacRegs->RX1HDP = 0;
    emacRegs->RX2HDP = 0;
    emacRegs->RX3HDP = 0;
    emacRegs->RX4HDP = 0;
    emacRegs->RX5HDP = 0;
    emacRegs->RX6HDP = 0;
    emacRegs->RX7HDP = 0;
    emacRegs->TX0HDP = 0;
    emacRegs->TX1HDP = 0;
    emacRegs->TX2HDP = 0;
    emacRegs->TX3HDP = 0;
    emacRegs->TX4HDP = 0;
    emacRegs->TX5HDP = 0;
    emacRegs->TX6HDP = 0;
    emacRegs->TX7HDP = 0;

//    4. Clear all 36 statistics registers by writing 0 (not necessary immediately
//        after reset).

    emacRegs->RXGOODFRAMES = 0;
    emacRegs->RXBCASTFRAMES = 0;
    emacRegs->RXMCASTFRAMES = 0;
    emacRegs->RXPAUSEFRAMES = 0;
    emacRegs->RXCRCERRORS = 0;
    emacRegs->RXALIGNCODEERRORS = 0;
    emacRegs->RXOVERSIZED = 0;
    emacRegs->RXJABBER = 0;
    emacRegs->RXUNDERSIZED = 0;
    emacRegs->RXFRAGMENTS = 0;
    emacRegs->RXFILTERED = 0;
    emacRegs->RXQOSFILTERED = 0;
    emacRegs->RXOCTETS = 0;
    emacRegs->TXGOODFRAMES = 0;
    emacRegs->TXBCASTFRAMES = 0;
    emacRegs->TXMCASTFRAMES = 0;
    emacRegs->TXPAUSEFRAMES = 0;
    emacRegs->TXDEFERRED = 0;
    emacRegs->TXCOLLISION = 0;
    emacRegs->TXSINGLECOLL = 0;
    emacRegs->TXMULTICOLL = 0;
    emacRegs->TXEXCESSIVECOLL = 0;
    emacRegs->TXLATECOLL = 0;
    emacRegs->TXUNDERRUN = 0;
    emacRegs->TXCARRIERSENSE = 0;
    emacRegs->TXOCTETS = 0;
    emacRegs->FRAME64 = 0;
    emacRegs->FRAME65T127 = 0;
    emacRegs->FRAME128T255 = 0;
    emacRegs->FRAME256T511 = 0;
    emacRegs->FRAME512T1023 = 0;
    emacRegs->FRAME1024TUP = 0;
    emacRegs->NETOCTETS = 0;
    emacRegs->RXSOFOVERRUNS = 0;
    emacRegs->RXMOFOVERRUNS = 0;
    emacRegs->RXDMAOVERRUNS = 0;

//    5. Setup the local Ethernet MAC address by programming the MAC index register
//        (MACINDEX), MAC address high bytes register (MACADDRHI), and MAC address low
//        bytes register (MACADDRLO). Be sure to program all eight MAC address registers
//        - whether the receive channel is to be enabled or not.Duplicate the same MAC
//        address across all unused channels. When using more than one receive channel,
//        start with channel 0 and progress upwards.

//        All eight addresses share the upper 40 bits. Only the lower byte is unique
//        for    each address. An address is written by first writing the address number
//        (channel) into the MACINDEX    register. The upper 32 bits of the address are
//        then written to the MACADDRHI register, which is followed by writing the
//        lower 16 bits of the address to the MACADDRLO register. Since all eight
//        addresses share the upper 40 bits of the address, the MACADDRHI register
//        only needs to be written the first time.

    emacRegs->MACINDEX = 0x0;

    CSL_FINS(emacRegs->MACADDRHI, EMAC_MACADDRHI_MACADDR5, 0x00);
    CSL_FINS(emacRegs->MACADDRHI, EMAC_MACADDRHI_MACADDR4, 0x0E);
    CSL_FINS(emacRegs->MACADDRHI, EMAC_MACADDRHI_MACADDR3, 0x99);
    CSL_FINS(emacRegs->MACADDRHI, EMAC_MACADDRHI_MACADDR2, 0x02);

    CSL_FINST(emacRegs->MACADDRLO, EMAC_MACADDRLO_VALID,VALID);
    CSL_FINST(emacRegs->MACADDRLO, EMAC_MACADDRLO_MATCHFILT, MATCH);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_CHANNEL, 0);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);

    emacRegs->MACINDEX = 1;
    CSL_FINST(emacRegs->MACADDRLO, EMAC_MACADDRLO_VALID,INVALID);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);

    emacRegs->MACINDEX = 2;
    CSL_FINST(emacRegs->MACADDRLO, EMAC_MACADDRLO_VALID,INVALID);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);

    emacRegs->MACINDEX = 3;
    CSL_FINST(emacRegs->MACADDRLO, EMAC_MACADDRLO_VALID,INVALID);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);

    emacRegs->MACINDEX = 4;
    CSL_FINST(emacRegs->MACADDRLO, EMAC_MACADDRLO_VALID,INVALID);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);

    emacRegs->MACINDEX = 5;
    CSL_FINST(emacRegs->MACADDRLO, EMAC_MACADDRLO_VALID,INVALID);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);

    emacRegs->MACINDEX = 6;
    CSL_FINST(emacRegs->MACADDRLO, EMAC_MACADDRLO_VALID,INVALID);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);

    emacRegs->MACINDEX = 7;
    CSL_FINST(emacRegs->MACADDRLO, EMAC_MACADDRLO_VALID,INVALID);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
    CSL_FINS(emacRegs->MACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);

}


But the emacRegs->MACADDRHI is locked to 0x02385926 and even in  Code Composer Studio I cannot modify this value.

What did I miss ?

Best regards

Arthur

  • The problem was that I made multiple access to MACADDRHI and MACADDRLO register to set the mac address, while it seems to be mandatory to set MACADDRHI in one write access and then MACADDRLO also in one write access. Here is the corrected code for the step 5 of the EMAC configuration :

    //    5. Setup the local Ethernet MAC address by programming the MAC index register
    //        (MACINDEX), MAC address high bytes register (MACADDRHI), and MAC address low
    //        bytes register (MACADDRLO). Be sure to program all eight MAC address registers
    //        - whether the receive channel is to be enabled or not.Duplicate the same MAC
    //        address across all unused channels. When using more than one receive channel,
    //        start with channel 0 and progress upwards.

    //        All eight addresses share the upper 40 bits. Only the lower byte is unique
    //        for    each address. An address is written by first writing the address number
    //        (channel) into the MACINDEX    register. The upper 32 bits of the address are
    //        then written to the MACADDRHI register, which is followed by writing the
    //        lower 16 bits of the address to the MACADDRLO register. Since all eight
    //        addresses share the upper 40 bits of the address, the MACADDRHI register
    //        only needs to be written the first time.

        UINT32 tmpMACADDRHI = 0, tmpMACADDRLO = 0;
        emacRegs->MACINDEX = 0x0;

        CSL_FINS(tmpMACADDRHI, EMAC_MACADDRHI_MACADDR5, 0x00);
        CSL_FINS(tmpMACADDRHI, EMAC_MACADDRHI_MACADDR4, 0x0E);
        CSL_FINS(tmpMACADDRHI, EMAC_MACADDRHI_MACADDR3, 0x99);
        CSL_FINS(tmpMACADDRHI, EMAC_MACADDRHI_MACADDR2, 0x02);
        emacRegs->MACADDRHI = tmpMACADDRHI;

        tmpMACADDRLO = 0;
        CSL_FINST(tmpMACADDRLO, EMAC_MACADDRLO_VALID, VALID);
        CSL_FINST(tmpMACADDRLO, EMAC_MACADDRLO_MATCHFILT, MATCH);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_CHANNEL, 0);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);
        emacRegs->MACADDRLO = tmpMACADDRLO;

        tmpMACADDRLO = 0;
        emacRegs->MACINDEX = 1;
        CSL_FINST(tmpMACADDRLO, EMAC_MACADDRLO_VALID, INVALID);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);
        emacRegs->MACADDRLO = tmpMACADDRLO;

        emacRegs->MACINDEX = 2;
        tmpMACADDRLO = 0;
        CSL_FINST(tmpMACADDRLO, EMAC_MACADDRLO_VALID, INVALID);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);
        emacRegs->MACADDRLO = tmpMACADDRLO;

        emacRegs->MACINDEX = 3;
        tmpMACADDRLO = 0;
        CSL_FINST(tmpMACADDRLO, EMAC_MACADDRLO_VALID, INVALID);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);
        emacRegs->MACADDRLO = tmpMACADDRLO;

        emacRegs->MACINDEX = 4;
        tmpMACADDRLO = 0;
        CSL_FINST(tmpMACADDRLO, EMAC_MACADDRLO_VALID, INVALID);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);
        emacRegs->MACADDRLO = tmpMACADDRLO;

        emacRegs->MACINDEX = 5;
        tmpMACADDRLO = 0;
        CSL_FINST(tmpMACADDRLO, EMAC_MACADDRLO_VALID, INVALID);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);
        emacRegs->MACADDRLO = tmpMACADDRLO;

        emacRegs->MACINDEX = 6;
        tmpMACADDRLO = 0;
        CSL_FINST(tmpMACADDRLO, EMAC_MACADDRLO_VALID, INVALID);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);
        emacRegs->MACADDRLO = tmpMACADDRLO;

        emacRegs->MACINDEX = 7;
        tmpMACADDRLO = 0;
        CSL_FINST(tmpMACADDRLO, EMAC_MACADDRLO_VALID, INVALID);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR1, 0xFE);
        CSL_FINS(tmpMACADDRLO, EMAC_MACADDRLO_MACADDR0, TDMA_DEVICE_NUMBER);
        emacRegs->MACADDRLO = tmpMACADDRLO;

    Best Regards

    Arthur