Hi.
I have problem with transmission of Ethernet frame.
When I captured a transmitted Ethernet frame at the other monitoring system, it looked like the Ethernet frame data was disordered.
I have set the source MAC address like a 0x11, 0x22, 0x33, 0x44, 0x55, 0x66
The captured packet showed disordered MAC address and wrong data length.(I set the frame length '18')
I'm considering that this problem caused by miss configuration of FEC DMA or Transmit Buffer Descriptor.
The Ethernet frame setting function likes below... (I referred MPC5646C FEC sample code)
void setupGlobalFrame()
{
int i;
frame = (void *) txBuf;
// Setup broadcast as destination
for (i = 0; i < 6; i++)
{
frame->destination[i] = broadcast[i];
}
// Setup source address
for (i = 0; i < 6; i++)
{
frame->source[i] = mac[i];
}
// Set length (static at 4 for the 32-bit data payload)
frame->length = 4;
// Setup txDesc for the (2x6-byte address + 2byte length + 4byte data) 18-byte frame
txDesc[0].length = 18;
txDesc[1].length = 18;
}
Also TBD settings are below
.....
for (i = 0; i < 2; i++)
{
// Init tx and rx descriptors
txDesc[i].status = 0x2C00; // Last and transmit CRC
txDesc[i].length = 0;
txDesc[i].bufferPointer = txBuf;
markRxDescEmpty(&rxDesc[i]);
rxDesc[i].bufferPointer = rxBuf[i];
}
....
FEC.ETDSR.R = (unsigned long) &txDesc;
In short, my questions are below
1. Is there any configuration for FEC DMA?
2. Possible miss-configuration of Transmit Buffer Descriptor? Any guesses?
Thank you.
Taekyoung Kim
Hello,
could you please share your project? I will check it on my side.
Regards,
Martin
I found the similar issue from FEC CodeWarrior MPC56xx - Tx repeting bytes
From that issue,
-------------------------------------------------------------------------------------------------------------------------------------------
This is very hard to explain if you have 32-bit memory and the FEC is reading 32 bits at a time, as it would require some intermediate "byte-lane changing hardware" to be doing something stupid.
It would be easier to understand if you've got 16-bit RAM, or a 16-bit pathway between the FEC and the RAM. the "pathway" is unlikely as the FEC is a master on the Crossbar.
-------------------------------------------------------------------------------------------------------------------------------------------
You can see that the transmitted Ethernet frame was duplicated 16 bit words.
ex) 11 22 11 22 11 22 11 22 11 22
Is this because Crossbar setting? or system clock?
I'm afraid not to share the project files for the security policy, but here are some functions related to FEC configuration.
#define OBE 0x0200
#define IBE 0x0100
#define ODE 0x0020
#define SRC 0x0004
#define WPE 0x0002
#define WPS 0x0001
#define PA_GPIO 0x0000
#define PA_PRIM 0x0400
#define PA_ALT1 0x0800
#define PA_ALT2 0x0C00
#define PA_ALT3 0x1000
#define SIU_SYSDIV_PERCLKSEL_NON_FM_CLOCK 0x1000000
#define SIU_SYSDIV_PERDIV_DIVIDE_BY_2 0x0000000
...
// initFecIo - initialise pads for FEC use in the SIU
void initFecIo(void)
{
// MPC5777C - FEC MII-Lite mode IO setting
SIU.PCR[PCR99_FEC_MDIO_ALT2].R = PA_ALT2 | OBE | IBE | SRC | WPE; //FEC_MDIO
SIU.PCR[PCR109_FEC_MDC_ALT3].R = PA_ALT3 | OBE | WPE; //FEC_MDC
SIU.PCR[PCR252_FEC_TX_EN_PRIM].R = PA_PRIM | OBE | SRC; //FEC_TX_EN
SIU.PCR[PCR248_FEC_TXD0_PRIM].R = PA_PRIM | OBE | SRC; //FEC_TXD0
SIU.PCR[PCR251_FEC_TXD1_PRIM].R = PA_PRIM | OBE | SRC; //FEC_TXD1
SIU.PCR[PCR98_FEC_TXD2_ALT2].R = PA_ALT2 | OBE | SRC; //FEC_TXD2
SIU.PCR[PCR101_FEC_TXD3_ALT3].R = PA_ALT3 | OBE | SRC; //FEC_TXD3
SIU.PCR[PCR474_FEC_TX_CLK_PRIM].R = PA_PRIM | IBE | WPE; //FEC_TX_CLK
SIU.PCR[PCR100_FEC_RX_CLK_ALT3].R = PA_ALT3 | IBE | SRC | WPE; //FEC_RX_CLK
SIU.PCR[PCR249_FEC_RX_DV_PRIM].R = PA_PRIM | IBE | WPE; //FEC_RX_DV
SIU.PCR[PCR250_FEC_RXD0_PRIM].R = PA_PRIM | IBE | SRC | WPE; //FEC_RXD0
SIU.PCR[PCR253_FEC_RXD1_PRIM].R = PA_PRIM | IBE | SRC | WPE; //FEC_RXD1
SIU.PCR[PCR101_FEC_RXD2_ALT3].R = PA_ALT3 | IBE | SRC | WPE; //FEC_RXD2
SIU.PCR[PCR107_FEC_RXD3_ALT3].R = PA_ALT3 | IBE | SRC | WPE; //FEC_RXD3
//Input Multiplexing Register0(SIU_IMUX0) setting for FEC input pins
SIU.IMUX0.R = IMUX0_MUXSEL6_FEC_TXCLK | IMUX0_MUXSEL1_FEC_RXDV | IMUX0_MUXSEL2_FEC_RXD0 | \
IMUX0_MUXSEL5_FEC_RXD1 | IMUX0_MUXSEL11_FEC_RXD2 | IMUX0_MUXSEL8_FEC_RXD3;
//Peripheral Clock Setting
SIU.SYSDIV.R = SIU_SYSDIV_PERCLKSEL_NON_FM_CLOCK | SIU_SYSDIV_PERDIV_DIVIDE_BY_2;
}
static int initFec(void)
{
int result = 1;
int i;
initFecIo();
FEC.ECR.R = 0x1;
while (FEC.ECR.B.RESET) { } ; // Wait for reset to complete
FEC.EIMR.R = 0; // Disable interrupts
FEC.EIR.R = 0xFFFFFFFF; // Clear any interrupts
for (i = 0; i < 2; i++)
{
// Init tx and rx descriptors
txDesc[i].status = 0x2C00; // Last and transmit CRC
txDesc[i].length = 0;
txDesc[i].bufferPointer = txBuf;
markRxDescEmpty(&rxDesc[i]);
rxDesc[i].bufferPointer = rxBuf[i];
}
// Reset multicast fields
FEC.GAUR.R = 0;
FEC.GALR.R = 0;
FEC.IAUR.R = 0;
FEC.IALR.R = 0;
// Set rx buf size
FEC.EMRBR.R = 1536;
// Point FEC to our (single) tx and rx descriptors
FEC.ETDSR.R = (unsigned long) &txDesc;
FEC.ERDSR.R = (unsigned long) &rxDesc;
// Enable full duplex
FEC.TCR.R = 0x00000004; //full duplex enable
// Set in MII mode with full frame size
FEC.RCR.R = 0x05EE0004;
// Set MII speed - assume operation at 64Mhz
FEC.MSCR.B.MII_SPEED = 0x5; // 50MHz(Internal bus clock) / 2 => 25 MHz
// Enable interrupt
FEC.EIMR.R = 0x02000000;
// Enable module
FEC.ECR.R = 0x2;
// Configure a MAC address
FEC.PALR.R = (unsigned long)((mac[0] <<24)|(mac[1] <<16)|(mac[2] <<8)|(mac[3] <<0));
FEC.PAUR.R = (unsigned long)(mac[4] <<24)|(mac[5] <<16);
initFecPhy();
// Flag descriptors available to allow reception
FEC.RDAR.R = 0x0100000;
return result;
}
int main(void)
{
volatile int counter = 0;
volatile int loop = 0;
STM_A.CR.R = 1; //System Timer Module
disableWatchdog();
xcptn_xmpl (); /* Configure and Enable Interrupts */
HW_init();
setMacAddr();
initFec();
setupGlobalFrame();
SIU.GPDO[LED1_pin].R = 0;
while(!isConnected());
/* Loop forever */
for(;;) {
while(loop <= 10000)
{
loop++;
}
SIU.GPDO[LED1_pin].R ^= 1;
txEthernetFrame();
loop = 0;
counter++;
}
}
Thank you.
Hello,
1) Please check if you have correctly aligned Buffer Descriptors and tx/rs buffers? Please see code below:
2) I am not sure about your MII_SPEED settings. FEC module is clocked from FM_PER_CLK. What is the value of your FM_PER_CLK?
MII Speed calculation is following FM_PER_CLK * ( 1/ (MSCR[MII_SPEED]*2)) <= 2.5MHz
Example:
FM_PER_CLK = 64MHz
Calculation: 64MHz * 1 / MSCR[MII_SPEED] * 2 <= 2.5MHz
Result: MSCR[MII_SPEED] = 13 (0xD)
Regards,
Martin
I have set SIU.SYSDIVE register like this
So FM_PER_CLK = 8MHz
- SYSCLKSEL : 0 (16MHz IRC)
- SYSCLKDIV : 0x4 (Divide by 1) -> 16MHz / 1 = 16MHz
- FMPERDIV : 0 (Divide by 2) -> 16MHz / 2 = 8MHz
FEC.MSCR.B.MII_SPEED = 0x2; // 8MHz x ( 1 / ( 2 x 2)) = 2MHz <= 2.5MHz
Is it correct?
Nevertheless, the result of transmitted Ethernet frame was same. (You can still see the duplicated data, 01 02 01 02...)
Please give me a feedback about my clock setting.
Thank you for your patience.
Regards
Taekyoung Kim
Hi,
Seems I was wrong last time, the FEC is actually clocked from FM_PER_CLK and so the MDC clock must be calculated from this FM_PER_CLK. Note this clock must be at least 50MHz so full duplex is supported.
If the MII-lite is used the following jumper setting must be done on minimodule and PHY on motherboard must be clocked from 25MHz crystal.
BR, Petr
I forgot to mention the development environment.
- MPC5777C-EVB Rev.C 516DS
- S32DS IDE
I would like to use MII-Lite interface.
1) I have same declaration for the Buffer Descriptors.
// Min 2 descriptors needed to prevent resending
BufferDescriptor txDesc[2] __attribute__ ((aligned (16)));
BufferDescriptor rxDesc[2] __attribute__ ((aligned (16)));
// We need 1518 bytes... but 1536 is evenly divisible by 16
uint8_t txBuf[1536] __attribute__ ((aligned (16)));
uint8_t rxBuf[2][1536] __attribute__ ((aligned (16)));
2) I had configured clock setting as you told, but same problem was occurred.
- My SIU.SYSDIV setting is below
- System clock setting
#define SIU_SYSDIV_SYSCLKSEL_FM_PLL1 0x00002000
#define SIU_SYSDIV_FMPERDIV_DIVIDE_BY_2 0x00000000
...
SIU.SYSDIV.R = SIU_SYSDIV_SYSCLKSEL_FM_PLL1 | SIU_SYSDIV_FMPERDIV_DIVIDE_BY_2;
- MII Speed setting
FEC.MSCR.B.MII_SPEED = 0xD;
According to the 'MPC5777C EVB user guide' (document number MPC5777CEVBUG, Rev0/2015)'
with that jumper setting, it enables FEC 50MHz clock. That's why I configured 'MII_SPEED' like
- on board 50MHz FEC clock / Divided by 2 -> (50MHz / 2) = 25MHz (Internal bus clock)
- FEC.MSCR.B.MII_SPEED = 0x5; // 25MHz(Internal bus clock) x (1 / (5 x 2)) =< 2.5 MHz
And 'Petr Stancik' told me in the previous question that (Questions of MPC5777C FEC setting)
'The MDC frequency is calculated from the internal bus clock, in this case it should be PER_CLK selected by SIU_SYSDIV.PERDIV'
Which register should I set for the FEC clock setting(MII-Lite interface)? PERCLKSEL or SYSCLKSEL?
I'm confused about FEC clock setting, please explain more detail about it.
(It would be a great help, if you list up all the registers to configure FEC clock)