FEC CodeWarrior MPC56xx - Tx repeting bytes

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

FEC CodeWarrior MPC56xx - Tx repeting bytes

Jump to solution
1,344 Views
mmdonatti
Contributor II

I've configured FEC in a MPC5604 to send frames to a PC. I sniffe PC ethernet port to verify that the data has been sent. It works, but the data received in PC is sometimes inverted or lost.

First, I configure I/Os, configure and start ethernet devices, configure the PHY with all reference manual recommandations, and it works perfectly. My TxBD buffer pointer is initialized with :

txDesc[0].length = 500;

for(i=0;i<500;i++)

       txBuf[i]=(unsigned char)i%256;

__flush_cache(txBuf,500);

After, I set the BD status and mark TDAR as ready to start :

txDesc[0].status = 0x8C00;

FEC.TDAR.B.X_DES_ACTIVE = 1;

When I sniffe PC ethernet port I have :

sniffer.png

For example, in the first packet, it loses 06 and 07 and sends 0a and 0b two times. (and this error occurs many times)

I also verified memory addresses and they are perfect : 01,02,03 ..., FF

I don't know if its an ethernet DMA problem or any register configuration. Anyone did have this same problem?

thank you

0 Kudos
1 Solution
839 Views
mmdonatti
Contributor II

I finally found the solution :

The system CLK didn't match with my MII configuration. I create a function to configure system CLK in RUN0 mode :

//Configure SYS_CLK from 25MHz XTAL

void configCLK(void)
{

ME.MER.R = 0x0000001D; // Enable DRUN, RUN0, SAFE, RESET modes
//Initialize PLL before turning it on:
//Set PLL value:
FMPLL.CR.B.IDF = 0b0100;
FMPLL.CR.B.ODF= 0b00;
FMPLL.CR.B.NDIV= 0b0110000;//Exit PLL : 120MHz
CGM.PLL_CLK_DIV.B.DIV=0;
CGM.SYSTEM_CLK_DIV.B.DIV=1;//SYS_CLK=120/2=60MHz
CGM.RTC_CLK_DIV.B.DIV=1;//RTC_CLK=60/2=30MHz

ME.RUN0.R = 0x001F0074; // RUN0 cfg: 16MHzIRCON,OSC0ON,PLL0ON,syclk=PLL0
ME.RUN_PC1.R = 0x00000010; //Peri. Cfg. 1 settings: only run in RUN0 mode
ME.PCTL68.R = 0x01; //MPC56xxB/S: select ME.RUNPC[1]
// Mode Transition to enter RUN0 mode:

ME.MCTL.R = 0x40005AF0; //Enter RUN0 Mode & Key
ME.MCTL.R = 0x4000A50F; //Enter RUN0 Mode & Inverted Key
while (ME.GS.B.S_MTRANS == 1) {} //Wait for mode transition to complete

while(ME.GS.B.S_CURRENT_MODE != 4){} // Verify RUN0 is the current mode 
}

And in the FEC configuration, I set MII_SPEED=0xC. From MPC5604ERM page 874:

" MII_SPEED controls the frequency of the MII management interface clock (FEC_MDC)

relative to the system clock. A value of 0 in this field “turns off” the FEC_MDC and leave

it in low voltage state. Any non-zero value results in the FEC_MDC frequency of

1/(MII_SPEED*2) of the system clock frequency.

The MII_SPEED field must be programmed with a value to provide an FEC_MDC frequency of less than

or equal to 2.5 MHz to be compliant with the IEEE 802.3 MII specification. The MII_SPEED must be set

to a non-zero value in order to generate a read or write management frame. After the management frame

is complete the MSCR can optionally be set to zero to turn off the FEC_MDC. The FEC_MDC generated

has a 50% duty cycle except when MII_SPEED is changed during operation (change takes effect following

either a rising or falling edge of FEC_MDC).

The FEC_MDC frequency depends on both the system clock frequency and the MII_SPEED register. If

the system clock is 25 MHz, programming the MII_SPEED register to 0x0000_0005 results in an

FEC_MDC frequency of 25 MHz * 1/10 = 2.5 MHz."

So, for SYS_CLK=60MHz :

FEC.MSCR.B.MII_SPEED=0xC;//set MDIO speed

Finally, it works perfectly.

Mauricio


View solution in original post

0 Kudos
3 Replies
840 Views
mmdonatti
Contributor II

I finally found the solution :

The system CLK didn't match with my MII configuration. I create a function to configure system CLK in RUN0 mode :

//Configure SYS_CLK from 25MHz XTAL

void configCLK(void)
{

ME.MER.R = 0x0000001D; // Enable DRUN, RUN0, SAFE, RESET modes
//Initialize PLL before turning it on:
//Set PLL value:
FMPLL.CR.B.IDF = 0b0100;
FMPLL.CR.B.ODF= 0b00;
FMPLL.CR.B.NDIV= 0b0110000;//Exit PLL : 120MHz
CGM.PLL_CLK_DIV.B.DIV=0;
CGM.SYSTEM_CLK_DIV.B.DIV=1;//SYS_CLK=120/2=60MHz
CGM.RTC_CLK_DIV.B.DIV=1;//RTC_CLK=60/2=30MHz

ME.RUN0.R = 0x001F0074; // RUN0 cfg: 16MHzIRCON,OSC0ON,PLL0ON,syclk=PLL0
ME.RUN_PC1.R = 0x00000010; //Peri. Cfg. 1 settings: only run in RUN0 mode
ME.PCTL68.R = 0x01; //MPC56xxB/S: select ME.RUNPC[1]
// Mode Transition to enter RUN0 mode:

ME.MCTL.R = 0x40005AF0; //Enter RUN0 Mode & Key
ME.MCTL.R = 0x4000A50F; //Enter RUN0 Mode & Inverted Key
while (ME.GS.B.S_MTRANS == 1) {} //Wait for mode transition to complete

while(ME.GS.B.S_CURRENT_MODE != 4){} // Verify RUN0 is the current mode 
}

And in the FEC configuration, I set MII_SPEED=0xC. From MPC5604ERM page 874:

" MII_SPEED controls the frequency of the MII management interface clock (FEC_MDC)

relative to the system clock. A value of 0 in this field “turns off” the FEC_MDC and leave

it in low voltage state. Any non-zero value results in the FEC_MDC frequency of

1/(MII_SPEED*2) of the system clock frequency.

The MII_SPEED field must be programmed with a value to provide an FEC_MDC frequency of less than

or equal to 2.5 MHz to be compliant with the IEEE 802.3 MII specification. The MII_SPEED must be set

to a non-zero value in order to generate a read or write management frame. After the management frame

is complete the MSCR can optionally be set to zero to turn off the FEC_MDC. The FEC_MDC generated

has a 50% duty cycle except when MII_SPEED is changed during operation (change takes effect following

either a rising or falling edge of FEC_MDC).

The FEC_MDC frequency depends on both the system clock frequency and the MII_SPEED register. If

the system clock is 25 MHz, programming the MII_SPEED register to 0x0000_0005 results in an

FEC_MDC frequency of 25 MHz * 1/10 = 2.5 MHz."

So, for SYS_CLK=60MHz :

FEC.MSCR.B.MII_SPEED=0xC;//set MDIO speed

Finally, it works perfectly.

Mauricio


0 Kudos
839 Views
TomE
Specialist II

You've been posting about this in the ColdFire Forum.

> sometimes inverted or lost.

Nothing is inverted and no data is getting "lost" in that there are no missing bytes in the data stream. It is repeating or duplicating 16-bit words.

How often does this happen? You've given two examples, both showing the problem. By "sometimes" do you mean "sometimes duplicates words" (about half the time from the above) or "sometimes sends packets like this"? Does it ever get it right?

This problem doesn't look like it is caused by the FEC. It looks more like a memory problem of some sort.

If you look "down the columns" of your screen captures (you could have done a cut/paste to get the raw text BTW) you'll see the first column always has "0" or "e" as the last digit and so on.

So it is always reading the expected 16-bit value or the PREVIOUS 16-bit value, and never any other data.

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've got 96k of SRAM in there. I thought you might be running from an external 16-bit RAM, but that chip doesn't seem to support that. So you have to have the rings and the buffers in the 96k Static RAM.

Are you obeying the buffer alignment requirements? If your buffer starts on an "Odd-1", "Odd-2" or "Odd-4" address instead of the required alignments. Ring pointers "must be 128-bit aligned." Also "The transmit buffer pointer contains the address of the associated data buffer, which is 16 byte aligned."

Tom

839 Views
mmdonatti
Contributor II

> The App Note qou quote is for the MPC564x? Does it apply to the MPC5604? Which MPC5604 are you using?

I'm using the MPC5604E. There is no application note for its FEC, so I base my code on AN4577 and MPC5604ERM

> How often does this happen? You've given two examples, both showing the problem. By "sometimes" do you mean "sometimes duplicates words" (about half the time from the above) or "sometimes sends packets like this"? Does it ever get it right?

I mean sometimes duplicate words. It's happening to all sent packets. No, it never works correctly.

>You've got 96k of SRAM in there. I thought you might be running from an external 16-bit RAM, but that chip doesn't seem to support that. So you have to have the rings and the buffers in the 96k Static RAM.

>Are you obeying the buffer alignment requirements? If your buffer starts on an "Odd-1", "Odd-2" or "Odd-4" address instead of the required alignments. Ring pointers "must be 128-bit aligned." Also "The transmit buffer pointer contains the address of the associated data buffer, which is 16 byte aligned."

Yes, the buffers descriptors and pointers are 16-byte aligned :

// Buffer Descriptors -- must be 16-byte aligned

//define unaligned BDs

static unsigned char unaligned_tx_nbuf[(sizeof(BufferDescriptor)*nbTxBD) + 16];

static unsigned char unaligned_rx_nbuf[(sizeof(BufferDescriptor)*nbRxBD) + 16];

//define unaligned buffers

//Data Buffers -- must be aligned on a 16-byte boundary

static unsigned char  unaligned_rx_buf[(ETH_MAX_LENGTH * nbRxBD) + 16];

static unsigned char  unaligned_tx_buf[(ETH_MAX_LENGTH * nbTxBD) + 16];

//align BDs and buffers

rxDesc = (BufferDescriptor *)((unsigned long)(unaligned_rx_nbuf + 16) & 0xFFFFFFF0);

rxBuf = (unsigned char *)((unsigned long)(unaligned_rx_buf + 16) & 0xFFFFFFF0);

txDesc = (BufferDescriptor *)((unsigned long)(unaligned_tx_nbuf + 16) & 0xFFFFFFF0);

txBuf = (unsigned char *)((unsigned long)(unaligned_tx_buf + 16) & 0xFFFFFFF0);

They are in SRAM. Verified by CodeWarrior :

txDesc: $4000C400

(*txDesc).bufferPointer : $4000A020

0 Kudos