Part Number: AM263P4
Other Parts Discussed in Thread: DP83869, SYSCONFIG, TCA6416, TCA6424
Tool/software:
Hi,
My customer wants to evaluate "Enet LwIP HTTP Server On Bare Metal (No-RTOS)" example on their custom board.
https://dev.ti.com/tirex/explore/content/mcu_plus_sdk_am263px_10_02_00_15/docs/api_guide_am263px/EXAMPLES_ENET_LWIP_CPSW_HTTPSERVER.html
This example works fine on Control Card.
There are a few difference on the custom board compared to Control Card.
- There is no EEPROM to store MAC address.
- There are two DP83867 Ethernet PHY. (one DP83869 on Control card)
The customer changed below points in sysconfig and codes.
Remove I2C:
Remove EEPROM:
Modify syscfg/ti_board_config.c:
- Remove EnetBoard_setMacPort2IOExpanderCfg() function
- Do not call EnetBoard_setMacPort2IOExpanderCfg() in EnetBoard_setupPorts() function.
- Just do "*pAvailMacEntries = 0;" in EnetBoard_getMacAddrList()
Modified ti_board_config.c
/* ========================================================================== */
/* Include Files */
/* ========================================================================== */
#include <stdint.h>
#include <enet.h>
#include "dp83867.h"
#include <enet_apputils.h>
#include <enet_appboardutils.h>
#include <drivers/hw_include/cslr_soc.h>
#include <networking/enet/core/src/phy/generic_phy.h>
#include <networking/enet/core/src/phy/enetphy_priv.h>
#include "ti_board_open_close.h"
#include <kernel/dpl/AddrTranslateP.h>
#include <ti_drivers_config.h>
#include <drivers/i2c.h>
#include <board/ioexp/ioexp_tca6424.h>
#include <board/ioexp/ioexp_tca6416.h>
static void EnetBoard_setMacPort2IOExpanderCfg(void);
/* PHY drivers */
extern Phy_DrvObj_t gEnetPhyDrvDp83867;
extern Phy_DrvObj_t gEnetPhyDrvGeneric;
/*! \brief All the registered PHY specific drivers. */
static const EthPhyDrv_If gEnetPhyDrvs[] =
{
&gEnetPhyDrvDp83867, /* DP83867 */
&gEnetPhyDrvGeneric, /* Generic PHY - must be last */
};
const EnetPhy_DrvInfoTbl gEnetPhyDrvTbl =
{
.numHandles = ENET_ARRAYSIZE(gEnetPhyDrvs),
.hPhyDrvList = gEnetPhyDrvs,
};
/* ========================================================================== */
/* Macros & Typedefs */
/* ========================================================================== */
/**
TPR:MSS_CTRL:CPSW_CONTROL
Address offset 0x0000016C
Physical address 0x0212016C
Instance MSS_CTRL
CPSW_CONTROL_RGMII1_ID_MODE 16 Writing 1'b1 would disable the internal clock delays. And those delays need to be handled on board.
CPSW_CONTROL_RMII_REF_CLK_OE_N 8 To select the rmii_ref_clk from PAD or from MSS_RCM. 0: clock will be from mss_rcm through IO internal loopback 1: will be from
CPSW_CONTROL_PORT1_MODE_SEL 2:0 Port 1 Interface
00 = GMII/MII
01 = RMII
10 = RGMII
11 = Not Supported
*/
#define MSS_CPSW_CONTROL_PORT_MODE_RMII (0x1U)
#define MSS_CPSW_CONTROL_PORT_MODE_RGMII (0x2U)
#define EEPROM_MAGIC_NUMBER_VAL (0xEE3355AAU)
#define EEPROM_MAGIC_NUMBER_OFFSET (0x0U)
#define EEPROM_READ_PCB_REV_DATA_OFFSET (0x0022)
#define I2C_EEPROM_MAC_DATA_OFFSET (0x3D)
#define I2C_EEPROM_MAC_CTRL_OFFSET (0x3B)
#define ENET_BOARD_NUM_MACADDR_MAX (3U)
#define ENET_GET_NUM_MAC_ADDR(num) ((num>>3)+1)
#define ENET_MAC_ADDR_VALIDATE_MASK (0x01U)
/* ========================================================================== */
/* Structure Declarations */
/* ========================================================================== */
/* None */
/* ========================================================================== */
/* Function Declarations */
/* ========================================================================== */
static const EnetBoard_PortCfg *EnetBoard_getPortCfg(const EnetBoard_EthPort *ethPort);
static const EnetBoard_PortCfg *EnetBoard_findPortCfg(const EnetBoard_EthPort *ethPort,
const EnetBoard_PortCfg *ethPortCfgs,
uint32_t numEthPorts);
static void EnetBoard_enableExternalMux();
/* ========================================================================== */
/* Global Variables */
/* ========================================================================== */
/*!
* \brief Common Processor Board (CPB) board's DP83867 PHY configuration.
*/
static const Dp83867_Cfg gEnetCpbBoard_ConfigEnetEthphy1PhyCfg =
{
.txClkShiftEn = false,
.rxClkShiftEn = false,
.txDelayInPs = 2000U, /* 2.00 ns */
.rxDelayInPs = 2000U, /* 2.00 ns */
.txFifoDepth = 4U, /* 4 bytes/nibbles */
.impedanceInMilliOhms = 50000U, /* 50 ohms */
.idleCntThresh = 5U,
.gpio0Mode = DP83867_GPIO0_RXERR,
.gpio1Mode = DP83867_GPIO1_COL,
.ledMode =
{
DP83867_LED_LINKED,
DP83867_LED_LINKED_1000BT,
DP83867_LED_RXTXACT,
DP83867_LED_LINKED_100BTX,
},
};
/*
* am263px-cc board configuration.
*
* RMII/RGMII PHY connected to am263px-cc CPSW_3G MAC port.
*/
static const EnetBoard_PortCfg gEnetCpbBoard_am263px_cc_EthPort[] =
{
{ /* "CPSW3G" */
.enetType = ENET_CPSW_3G,
.instId = 0U,
.macPort = ENET_MAC_PORT_2,
.mii = {ENET_MAC_LAYER_GMII, ENET_MAC_SUBLAYER_REDUCED},
.phyCfg =
{
.phyAddr = 0,
.isStrapped = false,
.skipExtendedCfg = false,
.extendedCfg = &gEnetCpbBoard_ConfigEnetEthphy1PhyCfg,
.extendedCfgSize = sizeof(gEnetCpbBoard_ConfigEnetEthphy1PhyCfg)
},
.flags = 0U,
},
};
/* ========================================================================== */
/* Function Definitions */
/* ========================================================================== */
const EnetBoard_PhyCfg *EnetBoard_getPhyCfg(const EnetBoard_EthPort *ethPort)
{
const EnetBoard_PortCfg *portCfg;
portCfg = EnetBoard_getPortCfg(ethPort);
return (portCfg != NULL) ? &portCfg->phyCfg : NULL;
}
static void EnetBoard_enableExternalMux()
{
/* Enable external MUXes, if any, as per the board design */
}
static const EnetBoard_PortCfg *EnetBoard_getPortCfg(const EnetBoard_EthPort *ethPort)
{
const EnetBoard_PortCfg *portCfg = NULL;
if (ENET_NOT_ZERO(ethPort->boardId & ENETBOARD_CPB_ID) ||
((portCfg == NULL) && ENET_NOT_ZERO(ethPort->boardId & ENETBOARD_LOOPBACK_ID)))
{
portCfg = EnetBoard_findPortCfg(ethPort,
gEnetCpbBoard_am263px_cc_EthPort,
ENETPHY_ARRAYSIZE(gEnetCpbBoard_am263px_cc_EthPort));
}
return portCfg;
}
static const EnetBoard_PortCfg *EnetBoard_findPortCfg(const EnetBoard_EthPort *ethPort,
const EnetBoard_PortCfg *ethPortCfgs,
uint32_t numEthPorts)
{
const EnetBoard_PortCfg *ethPortCfg = NULL;
bool found = false;
uint32_t i;
for (i = 0U; i < numEthPorts; i++)
{
ethPortCfg = ðPortCfgs[i];
if ((ethPortCfg->enetType == ethPort->enetType) &&
(ethPortCfg->instId == ethPort->instId) &&
(ethPortCfg->macPort == ethPort->macPort) &&
(ethPortCfg->mii.layerType == ethPort->mii.layerType) &&
(ethPortCfg->mii.sublayerType == ethPort->mii.sublayerType))
{
found = true;
break;
}
}
return found ? ethPortCfg : NULL;
}
void EnetBoard_getMiiConfig(EnetMacPort_Interface *mii)
{
mii->layerType = ENET_MAC_LAYER_GMII;
mii->variantType = ENET_MAC_VARIANT_FORCED;
mii->sublayerType = ENET_MAC_SUBLAYER_REDUCED;
}
int32_t EnetBoard_setupPorts(EnetBoard_EthPort *ethPorts,
uint32_t numEthPorts)
{
CSL_mss_ctrlRegs *mssCtrlRegs = (CSL_mss_ctrlRegs *)CSL_MSS_CTRL_U_BASE;
DebugP_assert(numEthPorts == 1);
DebugP_assert(ethPorts->mii.sublayerType == ENET_MAC_SUBLAYER_REDUCED);
EnetBoard_enableExternalMux();
switch(ethPorts->macPort)
{
case ENET_MAC_PORT_1:
CSL_FINS( mssCtrlRegs->CPSW_CONTROL,MSS_CTRL_CPSW_CONTROL_RGMII1_ID_MODE, 0U);
CSL_FINS( mssCtrlRegs->CPSW_CONTROL,MSS_CTRL_CPSW_CONTROL_PORT1_MODE_SEL, MSS_CPSW_CONTROL_PORT_MODE_RGMII);
break;
case ENET_MAC_PORT_2:
CSL_FINS( mssCtrlRegs->CPSW_CONTROL,MSS_CTRL_CPSW_CONTROL_RGMII2_ID_MODE, 0U);
CSL_FINS( mssCtrlRegs->CPSW_CONTROL,MSS_CTRL_CPSW_CONTROL_PORT2_MODE_SEL, MSS_CPSW_CONTROL_PORT_MODE_RGMII);
//// EnetBoard_setMacPort2IOExpanderCfg(); Do not call
break;
default:
DebugP_assert(false);
}
/* Nothing else to do */
return ENET_SOK;
}
/* Remove
static void EnetBoard_setMacPort2IOExpanderCfg(void)
{
EEPROM_Handle eepromHandle = gEepromHandle[CONFIG_EEPROM0];
uint8_t readBuffer[10] = {0};
uint8_t* pEepromRdPtr = (uint8_t *) &readBuffer;
int32_t status = SystemP_SUCCESS;
uint32_t magicNum = 0;
status = EEPROM_read(eepromHandle, EEPROM_MAGIC_NUMBER_OFFSET, pEepromRdPtr, 4);
memcpy(&magicNum, pEepromRdPtr, sizeof(uint32_t));
// Check magic number header
if (magicNum == EEPROM_MAGIC_NUMBER_VAL)
{
// Read from Am263Px PCB revision
status = EEPROM_read(eepromHandle, EEPROM_READ_PCB_REV_DATA_OFFSET, pEepromRdPtr, 2);
if ((pEepromRdPtr[0] == 'E') && (pEepromRdPtr[1] == '1')) // Checking PCB revision E1
{
DebugP_logInfo("AM263Px CC E1 Board found\r\n");
const uint32_t mdioMuxSelLine = 8*1 + 4; // PORT 1, PIN 4
const uint32_t rgmii1MuxSelLine = 8*0 + 2; // PORT 0, PIN 2
const uint32_t rgmii2MuxSelLine = 8*0 + 3; // PORT 0, PIN 3
static TCA6416_Config gTCA6416_Config;
TCA6416_Params TCA6416Params;
TCA6416_Params_init(&TCA6416Params);
status = TCA6416_open(&gTCA6416_Config, &TCA6416Params);
if (status == SystemP_SUCCESS)
{
// Configure as output
status = TCA6416_config(&gTCA6416_Config,
mdioMuxSelLine,
TCA6416_MODE_OUTPUT);
}
if (status == SystemP_SUCCESS)
{
status = TCA6416_setOutput(&gTCA6416_Config, mdioMuxSelLine, TCA6416_OUT_STATE_HIGH);
}
if (status == SystemP_SUCCESS)
{
// Configure as output *
status = TCA6416_config(&gTCA6416_Config,
rgmii1MuxSelLine,
TCA6416_MODE_OUTPUT);
}
if (status == SystemP_SUCCESS)
{
status = TCA6416_setOutput(&gTCA6416_Config, rgmii1MuxSelLine, TCA6416_OUT_STATE_LOW);
}
if (status == SystemP_SUCCESS)
{
// Configure as output
status = TCA6416_config(&gTCA6416_Config,
rgmii2MuxSelLine,
TCA6416_MODE_OUTPUT);
}
if (status == SystemP_SUCCESS)
{
status = TCA6416_setOutput(&gTCA6416_Config, rgmii2MuxSelLine, TCA6416_OUT_STATE_LOW);
}
}
else if (((pEepromRdPtr[0] == 'E') && (pEepromRdPtr[1] == '2')) || (pEepromRdPtr[0] == 'A')) // Checking PCB revision Rev E2/Rev A
{
DebugP_logInfo("AM263Px CC E2 Board found\r\n");
const uint32_t mdioMuxSel1Line = 8*2 + 2; // PORT 2, PIN 2
const uint32_t mdioMuxSel2Line = 8*2 + 3; // PORT 2, PIN 3
const uint32_t rgmii0MuxSelLine = 8*2 + 4; // PORT 2, PIN 4
const uint32_t rgmii1MuxSelLine = 8*0 + 2; // PORT 0, PIN 2
const uint32_t rgmii2MuxSelLine = 8*0 + 3; // PORT 0, PIN 3
static TCA6424_Config gTCA6424_Config;
TCA6424_Params TCA6424Params;
TCA6424_Params_init(&TCA6424Params);
status = TCA6424_open(&gTCA6424_Config, &TCA6424Params);
if (status == SystemP_SUCCESS)
{
// Configure as output
status = TCA6424_config(&gTCA6424_Config,
mdioMuxSel1Line,
TCA6424_MODE_OUTPUT);
}
if (status == SystemP_SUCCESS)
{
status = TCA6424_setOutput(&gTCA6424_Config, mdioMuxSel1Line, TCA6424_OUT_STATE_HIGH);
}
if (status == SystemP_SUCCESS)
{
// Configure as output
status = TCA6424_config(&gTCA6424_Config,
mdioMuxSel2Line,
TCA6424_MODE_OUTPUT);
}
if (status == SystemP_SUCCESS)
{
status = TCA6424_setOutput(&gTCA6424_Config, mdioMuxSel2Line, TCA6424_OUT_STATE_HIGH);
}
if (status == SystemP_SUCCESS)
{
// Configure as output
status = TCA6424_config(&gTCA6424_Config,
rgmii0MuxSelLine,
TCA6424_MODE_OUTPUT);
}
if (status == SystemP_SUCCESS)
{
status = TCA6424_setOutput(&gTCA6424_Config, rgmii0MuxSelLine, TCA6424_OUT_STATE_LOW);
}
if (status == SystemP_SUCCESS)
{
// Configure as output
status = TCA6424_config(&gTCA6424_Config,
rgmii1MuxSelLine,
TCA6424_MODE_OUTPUT);
}
if (status == SystemP_SUCCESS)
{
status = TCA6424_setOutput(&gTCA6424_Config, rgmii1MuxSelLine, TCA6424_OUT_STATE_HIGH);
}
if (status == SystemP_SUCCESS)
{
// Configure as output
status = TCA6424_config(&gTCA6424_Config,
rgmii2MuxSelLine,
TCA6424_MODE_OUTPUT);
}
if (status == SystemP_SUCCESS)
{
status = TCA6424_setOutput(&gTCA6424_Config, rgmii2MuxSelLine, TCA6424_OUT_STATE_LOW);
}
}
else
{
DebugP_logInfo("AM263Px CC Unable to get version\r\n");
status = SystemP_FAILURE;
}
}
else
{
DebugP_logInfo("AM263Px CC EEPROM NOT FOUND or CURRUPTED\r\n");
status = SystemP_FAILURE;
}
}
*/
// Just do *pAvailMacEntries = 0;
void EnetBoard_getMacAddrList(uint8_t macAddr[][ENET_MAC_ADDR_LEN],
uint32_t maxMacEntries,
uint32_t *pAvailMacEntries)
{
*pAvailMacEntries = 0;
}
/* Remove
void EnetBoard_getMacAddrList(uint8_t macAddr[][ENET_MAC_ADDR_LEN],
uint32_t maxMacEntries,
uint32_t *pAvailMacEntries)
{
int32_t status = ENET_SOK;
uint32_t macAddrCnt;
uint32_t i;
uint8_t numMacMax;
uint8_t macAddrBuf[ENET_BOARD_NUM_MACADDR_MAX * ENET_MAC_ADDR_LEN];
uint8_t validNumMac = 0U;
status = EEPROM_read(gEepromHandle[CONFIG_EEPROM0], I2C_EEPROM_MAC_CTRL_OFFSET, &numMacMax, sizeof(uint8_t));
EnetAppUtils_assert(status == ENET_SOK);
EnetAppUtils_assert(ENET_GET_NUM_MAC_ADDR(numMacMax) <= ENET_BOARD_NUM_MACADDR_MAX);
EnetAppUtils_assert(pAvailMacEntries != NULL);
macAddrCnt = EnetUtils_min(ENET_GET_NUM_MAC_ADDR(numMacMax), maxMacEntries);
status = EEPROM_read(gEepromHandle[CONFIG_EEPROM0], I2C_EEPROM_MAC_DATA_OFFSET, macAddrBuf, (macAddrCnt * ENET_MAC_ADDR_LEN) );
EnetAppUtils_assert(status == ENET_SOK);
// Save only those required to meet the max number of MAC entries *
// Validating that the MAC addresses from the EEPROM are not MULTICAST addresses
for (i = 0U; i < macAddrCnt; i++)
{
if(!(macAddrBuf[i * ENET_MAC_ADDR_LEN] & ENET_MAC_ADDR_VALIDATE_MASK)){
memcpy(macAddr[validNumMac], &macAddrBuf[i * ENET_MAC_ADDR_LEN], ENET_MAC_ADDR_LEN);
validNumMac++;
}
}
*pAvailMacEntries = validNumMac;
if (macAddrCnt == 0U)
{
EnetAppUtils_print("EnetBoard_getMacAddrList Failed - IDK not present\n");
EnetAppUtils_assert(false);
}
}
*/
/*
* Get ethernet board id
*/
uint32_t EnetBoard_getId(void)
{
return ENETBOARD_AM263PX_EVM;
}
void Board_init(void)
{
}
void Board_deinit(void)
{
}
Set PHY part# in sysconfig:
Part# is DP83867. PHY address is 0x3 for port1, 0xC for port2.

Configure MAC address:
Assignment Method is "Manual Entry"
70:ff:76:1d:ec:f2(MAC port1)
70:ff:76:1d:ec:e3(MAC port2)

Configure Static IP: App_allocateIPAddress() in app_main.c
#define IP_ADDR_POOL_COUNT (2U)
const ip_addr_t gStaticIP[IP_ADDR_POOL_COUNT] = { IPADDR4_INIT_BYTES(192, 168, 1, 200) /* For NetifIdx = 0 */, IPADDR4_INIT_BYTES( 10, 64, 1, 200) /* For NetifIdx = 1 */};
(OR)
const ip_addr_t gStaticIP[IP_ADDR_POOL_COUNT] = { IPADDR4_INIT_BYTES(192, 168, 0, 2) /* For NetifIdx = 0 */, IPADDR4_INIT_BYTES( 10, 64, 0, 2) /* For NetifIdx = 1 */};
const ip_addr_t gStaticIPGateway[IP_ADDR_POOL_COUNT] = { IPADDR4_INIT_BYTES(192, 168, 1, 1) /* For NetifIdx = 0 */, IPADDR4_INIT_BYTES( 10, 64, 1, 1) /* For NetifIdx = 1 */};
const ip_addr_t gStaticIPNetmask[IP_ADDR_POOL_COUNT] = { IPADDR4_INIT_BYTES(255,255,255,0) /* For NetifIdx = 0 */, IPADDR4_INIT_BYTES(255,255,252,0) /* For NetifIdx = 1 */};
static void App_allocateIPAddress()
{
sys_lock_tcpip_core();
for (uint32_t netifIdx = 0U; netifIdx < ENET_SYSCFG_NETIF_COUNT; netifIdx++)
{
netif_set_addr(g_pNetif[NETIF_INST_ID0 + netifIdx],
&gStaticIP[NETIF_INST_ID0 + netifIdx],
&gStaticIPNetmask[NETIF_INST_ID0 + netifIdx],
&gStaticIPGateway[NETIF_INST_ID0 + netifIdx]);
}
sys_unlock_tcpip_core();
return;
}
When running the example, Ethernet link-up fails. Here is CSS log:
[Cortex_R5_0]
==========================
CPSW LWIP HTTP WEB SERVER
==========================
EnetAppUtils_reduceCoreMacAllocation: Reduced Mac Address Allocation for CoreId:0 From 4 To 2
Mdio_open:318
Open MAC port 2
Mdio_manual_ioctl_handler_ENET_MDIO_IOCTL_C22_READ:495
EnetMod_ioctl:1603
EnetPhyMdioDflt_readC22:296
EnetPhy_readReg:646
PHY 3 is alive
PHY 12 is alive
Starting lwIP, local interface IP is dhcp-enabled
[LWIPIF_LWIP] NETIF INIT SUCCESS
Host MAC address-0 : 70:ff:76:1d:ec:f2
Enet IF UP Event. Local interface IP:0.0.0.0
Enet IF UP Event. Local interface IP:192.168.1.200
[No more log after this point]FYI, below is the log with Control Card. Link-up is OK:
[Cortex_R5_0]
==========================
CPSW LWIP HTTP WEB SERVER
==========================
EnetAppUtils_reduceCoreMacAllocation: Reduced Mac Address Allocation for CoreId:0 From 4 To 2
Open MAC port 2
EnetPht_bindDriver:1873
PHY 0 is alive
EnetMod_ioctl:1603
Starting lwIP, local interface IP is dhcp-enabled
[LWIPIF_LWIP] NETIF INIT SUCCESS
Host MAC address-0 : 70:ff:76:1d:ec:f2
Enet IF UP Event. Local interface IP:0.0.0.0
Enet IF UP Event. Local interface IP:192.168.0.2
Cpsw_handleLinkUp:1626
MAC Port 2: Link up
Network Link UP Event
Network is UP ...
Are there anything missed in their setup?
The customer found below E2E. According to this thread, a few more configurations are needed.
- Adding EXTPHY
- Adding handle in structure
Are they needed?
https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1334440/am2632-dp83867-ethernet-phy-driver-support-in-sdk/5091192?tisearch=e2e-sitesearch&keymatch=AM263x%20DP83867#
Thanks and regards,
Koichiro Tashiro


