Etherner Driver on MCF52235

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

Etherner Driver on MCF52235

6,382 Views
Ricardo_RauppV
Contributor I
Hi People
I cannot send a basic ARP packet from my 52233 EVBoard.
Well, in fact I migrated my NE64 stack to ColdFire, and such driver was working perfect in NE64.
Of course NE64 has simpler structure FEC device.
The top point of my doubt is the fact I can see the descriptor ring filled with the Ready bit (tx) status + TC + L , data buffers address, etc etc, . but is keeps it forever, I mean the R bit should be cleared by the FEC after consumes this tx buffer (after setting the descriptor active bit ..)
I took a look in the ColdFire Book pg 253 and Internichie stack to compare their approachs to the mine and I didn´t see notihing special.
I also tried the CFinit, but I didn´t have success.
I aligned the data buffers and ring pointers as specified, but ...
Does any know if there is a kind of special *trick* (possible bug?) in this sense, once this chip is pretty new?
.. like..is there a very restrict sequence to initizalize something (MAC / PHY / rings desc. etc..) ?
or read before write some register?
 
I suspect the dualport RAM funcionality was failing but I could check its value and I understood is ok.
Some values / address of my design
 
Flash Address = 0x0000_0000
RAM address = 0x2000_0000
RAMBAR = 0x2000_0201
SCM_RAMBAR = 2000_0200  (IPSBAR+8 content)
 
Thanks !!!
 
 
 
 
 
 
Labels (1)
0 Kudos
Reply
14 Replies

997 Views
Jaux
Contributor I
Ricardo,

I am also toiling thru the EPHY and PHY trying to do my own thing.

I am using Embedded Forth ( SwiftX from Forth Inc ).

This is a long shot, but try the following: ( stick to the initialization sequence per the Interniche example.)

1. First get the EPHY going - such that the physical connection can happen even before you do the FEC inits.

2. Then do the setup for the FEC - I have given up to undertand why, I just slave onto the sequence sequence per Interniche.

By the way - the RM (p19-23) indicate a "t Start-up" from when EPHYEN is asserted till MDIO can commence. Any idea how long this time is?

BR, John Ulyate
0 Kudos
Reply

997 Views
Ricardo_RauppV
Contributor I
 
Great Jaux...!!!
Allways helping someone ...nice to hear you again...
 
In fact I tried to base my routine per the Internichie one, but I confess I got pretty scared.
There are some points I didin´t understand, for example, I understood they turn the Phy clock *before* conclude the total ePhy initialization...as mentioned at Freescale RM.
However, after several maneuvers over such code, I decided to in deep understand the FEC/Phy restrictions,functionality,initialization sequence,etc ...and I concluded the routine below would be the 100% correct and *clear* in order to put the FEC work correctly...
But..you know... thoughts are houghts , code is code , and so ...it didn´t work too.
I suspect there is a verysmall detail I´m not respecting, becuase, as I mentioned above, I believe each of the lines below, and its order, makes sense ...
However I will try some work based on your tips...
Thank you ..again ...
 
void mcf52233_ethernet_init(void)
{
unsigned long loop_counter;
 // reset the FEC
 MCF_FEC_ECR = MCF_FEC_ECR_RESET;
 while (MCF_FEC_ECR & MCF_FEC_ECR_RESET);
 // Configure interrupt registers (no interrupts)
 MCF_FEC_EIMR = 0;
 // clear any pending events */
   MCF_FEC_EIR = 0;
 // Configure Ethernet hash table bits
 MCF_FEC_GAUR = 0;
 MCF_FEC_GALR = 0;
 MCF_FEC_IAUR = 0;
 MCF_FEC_IALR = 0;
 MCF_FEC_PALR = 0x22334455; // address=0x001122334455;
 MCF_FEC_PAUR = 0x00110000;
 //
    // buffer rx size (EMAC_BUFFERS_SIZE=1520 -> defined at .h file)
 MCF_FEC_EMRBR=EMAC_BUFFERS_SIZE;
 // Configure FEC receiver mode: (MII mode+full_duplex)
 MCF_FEC_RCR = (MCF_FEC_RCR_MAX_FL(EMAC_BUFFERS_SIZE) |
                 MCF_FEC_RCR_MII_MODE);
 // tx/rx fifo boundary
 MCF_FEC_FRSR = 0x00000500;
 // tx watermark
 MCF_FEC_TFWR = 0;
 // Configure FEC transmitter mode: 
 MCF_FEC_TCR = ( 0
                | MCF_FEC_TCR_FDEN);    // full duplex
 // Configure MII interface speed. Must be <= 2.5MHz.
   // 60.000/(12*2)=2.5MHz
  MCF_FEC_MSCR = MCF_FEC_MSCR_MII_SPEED(12);
 // ini eth descriptors Tx/Rx
 init_eth_ring_descriptors();
 //
    // pointer to BDTx
 MCF_FEC_ETDSR=MCF_FEC_ETDSR_X_DES_START((uint32)ptr_eth_bd_tx);
    // pointer to BDRx
 MCF_FEC_ERDSR=MCF_FEC_ERDSR_R_DES_START((uint32)ptr_eth_bd_rx);
 //
 // enable MIB
 MCF_FEC_MIBC &= ~MCF_FEC_MIBC_MIB_DISABLE;
 //
 MCF_FEC_ECR = MCF_FEC_ECR_ETHER_EN;
 
 //
 // init ePHY
 //
   /* Set EPHY address to 0 */
   MCF_PHY_EPHYCTL1 = 0;
   /* Disable PHY clocks
      (Do not turn on PHY clocks until EMAC and EPHY are completely set up)
   */
   MCF_PHY_EPHYCTL0 = MCF_PHY_EPHYCTL0_DIS100 |
                      MCF_PHY_EPHYCTL0_DIS10  |
                      MCF_PHY_EPHYCTL0_LEDEN;
   /* Disable auto-negotiation */
   MCF_PHY_EPHYCTL0 |= MCF_PHY_EPHYCTL0_ANDIS;
   /* Enable EPHY */
   MCF_PHY_EPHYCTL0 |= MCF_PHY_EPHYCTL0_EPHYEN;
   /* Delay (2 seconds?) for startup time */
   for (loop_counter = 20000000; loop_counter != 0; loop_counter--);
   /* Configure link speed = 100 Mbps, full-duplex through MII interface...
      Write to MMFR to generate MII Write Frame to EPHY Control Register
      (Register 0), DATA = 0x2100
   */
   MCF_FEC_MMFR = MCF_FEC_MMFR_ST(0x1)      |
                  MCF_FEC_MMFR_OP(0x1)      |
                  MCF_FEC_MMFR_TA(0x2)      |
                  MCF_FEC_MMFR_DATA(0x2100);
   /* Poll for MII Write Frame completion */
   while ((MCF_FEC_EIR & MCF_FEC_EIR_MII) == 0);
   /* Clear MII status bit */
   MCF_FEC_EIR |= MCF_FEC_EIR_MII;
   /* Turn on 100Base-TX PHY clock */
   MCF_PHY_EPHYCTL0 &= ~MCF_PHY_EPHYCTL0_DIS100;
}
0 Kudos
Reply

997 Views
Jaux
Contributor I

Always a pleasure ...

I will study your code - I have read somewhere that you start with the EPHY, get it running and then do the FEC

Q : Can you get the EPHY to connect, ( 100mbs, F/D A-N) without starting up the FEC?

I have attached my forth code, FYI

BR

 

Ephy.txt

Message Edited by t.dowe on 2009-09-02 05:07 PM
0 Kudos
Reply

997 Views
Ricardo_RauppV
Contributor I
Hi Jaux
Follow some Chris´  (from Wildrice forum) comments about my code ...
BR
 
Hi Ricardo,
 A few things I have noticed:-

   for (loop_counter = 20000000; loop_counter != 0; loop_counter--);

Most compilers will optimise out a loop like this unless you decare loop_counter to be volatile.

MCF_FEC_EIMR = 0;

I think this should be

   MCF_FEC_EIR = 0xFFFFFFFF;            // Clear any interrupts

I.e. each bit that is 1 clears the corresponding interrupt.

MCF_FEC_PALR = 0x22334455; // address=0x001122334455;
MCF_FEC_PAUR = 0x00110000;

I think this a actually sets a mac address of 22-33-44-55-00-11. My code looks like this:

   MCF_FEC_PALR = *(uint32*)&hard_addr.addr[0];// Set mac address for the controller
   MCF_FEC_PAUR = (*(unit16*)&hard_addr.addr[4]) << 16;

Where hard_addr is a six byte array in the order mac addresses are usuallly written in.


Have you assigned the I/O pins to the ethernet controller whith soimething like this:-
   /* Enable FEC pins */
   
   MCF_GPIO_PAR_FEC = ( 0
               | MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC
               | MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC );
               
   MCF_GPIO_PAR_FECI2C = ( 0
               | MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC
               | MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO );       

I am using a 5373 but I expect the 52233 will need something similar.


Hope this helps,
   Chris

 
0 Kudos
Reply

997 Views
Jaux
Contributor I
Ricardo, I have found your problem - are you still interested?
0 Kudos
Reply

997 Views
Ricardo_RauppV
Contributor I
Hi Dr. Jaux !!
Yes..I really curious (and upset)  about my bug.
In  fact after rewite and copy and etc etc the code started to work, but I´m not convinced why?I´m pretty confused to *produce buffers+ risc engine and its procedures* ...
I asked Freescale support for this last issue but they didn´t answer me yet...
I can reply to ARP and PING packets, but I´m not secure about the *backgorund behavior * of my code regarding FEC/PHY.
I would appreciate your help ..once more  :smileyhappy:
Thanks man ...
0 Kudos
Reply

997 Views
Jaux
Contributor I
Ok, here goes...

You have to understand that I developed the ePHY/FEC driver in forth (SwiftX) and NOT in C and NOT using Codewarrior.

I am going to give you an English high-level narrative of what must be done, and if you want me to elaborate, let me know where...

1. The very first thing you have to do is to get the basic MCU running - PLL set to 60 MHz off a 25 MHz Xtal.

2. Next you have to get the ePHY configured and have it to connect to another 100mbit device in full-duplex mode. Enable the interrupts, but keep stubs in the vectored routines.

3. Next, configure the PHY with a MAC addr that start with 00:... and configure for promiscuous mode.

4. Set up your Tx and Rx buffer descriptors. The M52235 has little enough RAM, so I would suggest 2 Tx and 2 Rx rings. Remember the FEC keeps its own pointer into the BD's and you have to keep track of where you are in the ring buffers. Use the two TO/RO bits for this. I would suggest a permanent 2x$600 byte buffer area for the Rx buffer, and a dynamic buffer for Tx.

You got to tell FEC where the BD's reside in memory, how big the buffer area is and remember to include the L (last frame) bit in the last BD. Also remember to set the TC bit for the last Tx frame.

5. Enable the FEC, construct a test package that mimic the PING first frame sequence, assert TDAR and RDAR and watch the blinking lights. It will help if you run something like Ethereal on the "other" PC so you can track the packages (free at http://www.ethereal.com)

This is ePHY/FEC 101 in a nutshell. Oh and don't worry about the RISK engine, it runs by itself

John
0 Kudos
Reply

997 Views
mjbcswitzerland
Specialist V
Hi John

The configuraton of the RX buffers is an interesting point which is causing some discussion here. We have been using the M5223X for variosu projects since mid summer 2006 and have found that 2 x full frame Rx buffers are very prone to overrun when serving web pages with multiple connections (happens when service pages with graphics and other such integrated links).

It is typcial that due to the multiple connections there are a number of small frames received in a very short period fo time - say 3 to 5 acks within 50us. This immediately results in lost frames and TCP repetitions since 2 x 1k5 buffers are filled by the first acks and the following can not be accepted until the buffers are free again.

Therefore rather more buffers are useful.

Then there is the possibility of using a larger number of smaller buffers (say 256 byte). The advantage is that a barrage of short fast frames can be handled without any big problems as there are enough free small buffers (using a large number of large buffers is possible but obvioulsy eats into the SRAM, thus taking this space away from the application, which may need it). The disadvantage of small frames is that the receiver has to piece them together again - which is not difficult. What is more tricky is the fact that there will be loop backs from the last buffer to the first buffer - ie. a frame can begin in one of the last buffers and end in one of the first buffer - it is not in linear memory and so the TCP/IP stack handling it can not simply handle it as a message in a buffer, unless it is first copied to a 1k5 linear buffer in memory.
This copy reduces speed efficiency.

I am wondering whether there are other techniqies to use the advantages of small buffers but still enable a simple linear handling in the TCP/IP stack without the need to copy the data from the receive buffers to a linear buffer???

Any ideas or experience?

Regards

Mark Butcher

www.uTasker.com
0 Kudos
Reply

997 Views
Jaux
Contributor I
Hi Mark,

It is only the faithfull that still work this time of the year!

Just remember that I am developing my software for the M52235 in Embedded Forth called SwiftX - it beats code done in C/C++ via CW pants down. I will strongly reccomend you look at it.

I developed my stack from scratch - I have studied the RM, then hounded Freescale until they fixed the mistakes, then re-studied RM ver 2 and found more mistakes. I also studied the stack developed by Interniche, but in the porting process they lost beauty and ellegance and made spagetti, so I started from scratch...

What I have is a simple stack consisting of the machine interface ( ePHYInit and FECInit), a ARP/IP handler, an TCP/UDP/ICMP layer and the HTTP layer.

I ended up with 4 Rx buffers of $600 bytes and 2 x Tx buffers of $800 bytes each and the buffer info processing is done by the different protocol handlers directly on the data in the buffer using pointers - no moving stuff around. The buffers are in contigeous SRAM, and in some cases frame processing can chase around the loop.

I have two suspended tasks that each handle 1 and multiple frames which get awakened by ISR's servicing RXF and RXB. FEC-RXF will process the next frame and go to sleep where RXB will stay awake till the last frame in a sequence is processed.

I have run several tests with a lot of small packets - no problem, but if you have multiple client connecting you technically consume and occupy a buffer per client and can end up with race conditions.

I have an "unofficial" handshake mechanism that forces synch and eliminate the lost TCP frames. I also maintain specialized pointers for this.

I our application it will be unlikely for a lot of clients to access the little mini webserver running on the M5223x - we have diskless PC with a lot of RAM ( also running Forth, called SwiftForth ) for this purpose.

I hope this makes sence - let me know if I must lower the baud-rate.

( In Forth we would say : Mark GotIt IF ." Clever Man" ELSE TRUE VERBOSE ! 9600 BAUD-RATE ! RE-RUN THEN )

As I have said before, I had a look at you website and you make some very nice equipment - I would love to supercharge them with Forth-based applications.

BR, John
0 Kudos
Reply

997 Views
mjbcswitzerland
Specialist V
Hi John

Interesting stuff - but I am still waiting for figures to compare :smileywink:

Do you know how many people (can) program in Forth? What is the code size like and what are the advantages when developing. At the end of the day the code is running as machine code and it is the conversion between idea and binary which is the important point here.

What is portability like?
Our uTasker project can be compiled to the M5223X, NE64, SAM7X, STR912F and (soon) LPC23XX by changing a compiler switch (of course the hardware interface is switched in from the corresponding 'library').

We work only rarely with CW (although it is not that bad a tool at all for hardware debugging). Development is using VisualStudio (the world's best debugger as far as I know - it does many things like stack-integrity checking while running the real embedded code in real-time on the simulated target - immediately catching 'silly' errors which can be very difficult to find otherwise) and the chip runs in a simulator environment allowing testing of more or less everything in a project before burning to the real chip.

We can debug remote problems from Ethereal recordings (playing back the recording through the real code - exercising even the interrupt routines involved). The simulated chip communicates with the real network in 'real-time' by 'hijacking' the NIC in the developers PC - it has its own IP and MAC address which is 'unknown' to the developer's PC (bypassing any Firewalls) and so the local PC can communicate with the simulated target 'believing' it to be really out there on the network somewhere. It can be put in a Demiliterized zone in a network for real communication on the Internet with no risk to the local PC. The UARTs in the simulated chip are mapped to COM ports and various peripherals like I2C RTCs or SPI EEPROM exist in the virtual enviroment, enabling these also to be developed with in the project without the need for real hardware.

There is a strong user base which is continuing to grow rapidly.

Do you see that there is a market for Forth? How many developers use it and/or can be converted due to its advantages? Do you see a possibility of supporting Forth as an option in the existing uTasker environment? How much work would be involved to do this? Since C/(C++) tends still to be the standard language for developing typical embedded project in this class (BSD, UNIX, LINUX on the larger platforms and many smaller RTOS and TCP/IP stacks) I am still rather sceptical. But I am listening in case the arguments are convincing because the ultimate goal is to get from idea to machine code in the shortest amount of time and achieving the suitable level of code accuracy, portability and maintainability. If there are ways to improve it they need to be investigated further!

Regards

Mark
0 Kudos
Reply

997 Views
Jaux
Contributor I
Hi Mark,

I am just a humble user of SwiftX - you will find answers to all your questions in here : http://www.forth.com/embedded

I am very curios to compare the performances of the two stacks - to compare apples to apples, shall we agree on some standardized benchmark?

Yes, I agree, at the end is just machine code that gets executed. I can tell you from past experience that the real issue here is the time and expense applied to understand, design, develop and debug and then to deploy the solution. The real pain is the development and debug phase – this is the real time toilet. I am not shooting down any other development tool – each to it’s own, but I have found after evaluating most of the commercial tools that I always run back home to Momma.

And yes, I also agree with you that C and C++ is the Industry Standard and used in all the major systems. The embedded game however is a different animal altogether. Here the emphasis is on speed and code-size and I have found that the code generated by SwiftX is so much more compact, reliable and faster than code generated by CW and others.

We exclusively use only Freescale Si – I have a deep respect for their quality and robustness – I have yet to succeed to destroy any Freescale device with normal handling and operational procedures.

Oh yes – have a prosperous and happy 2007.

BR, John
0 Kudos
Reply

997 Views
rocco
Senior Contributor II
Hi, John and Mark:

Jaux wrote:
. . . Here the emphasis is on speed and code-size and I have found that the code generated by SwiftX is so much more compact, reliable and faster than code generated by CW and others.
I have not used Forth in years, but I can attest to the accuracy of John's statement. I do not consider Forth a high-level language, but a mid-level language, somewhere between assembler and C. This makes it suited for embedded development.

Forth is a unique language, in that it is built on the concept of the stack. If you can get use to the old Hewlett-Packard "reverse-Polish-notation" calculators, you can program in Forth. Because the language requires the programmer to manage the stack, the function call/return sequences tend to be more concise, as opposed to when the intricacies of the stack are 'hidden'.

Of course, a C or C++ programmer who understands the language's calling conventions could certainly do as well. But the point of the higher level languages is for the programmer to not have to concern herself with those details. I doubt many C programmers know how their function calls are implemented, whereas a Forth programmer has to.

I stopped using Forth when I migrated to the HC05, which didn't have a stack that you could access.

Message Edited by rocco on 2007-01-0101:10 PM

0 Kudos
Reply

997 Views
Jaux
Contributor I
Hi Rocco,

Have a look at what Forth Inc has done with forth - you will be pleasantly surprised. They have just ported it to run on the HCS08 core, and in the past 6 months I have successfully developed and deployed 5 projects involving the HCS08GB60 and HCS08AW60 and 30 MCU's.

It was quick, easy and painless.

I will be doing a write-up on those projects and post it on Forth Inc's website soon.

John
0 Kudos
Reply

997 Views
Jaux
Contributor I
Ok...

1. You got to clear the interrupt flag by reading MCF_FEC_EIR, then mask the interrupt bit.
2. Any polling into the MII must be doine with the interrupt masked.
3. Some comments from ifec.c ( complements to Interniche)

/* Note that the FEC "likes" some MAC Addrs and doesn't "like" others at all!
*
* The following is an example of a MAC Addr that the FEC will NOT recognize
* or respond to at all. The symptoms are that it will reply to an ARP Request
* but will ignore any subequent frames addressed to this MAC Addr.
*
* unsigned char mac_addr_fec[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0, 0 };
*
* Note: This is a multicast address, and the syptoms are consistent with this.
* It's not the FEC; the address really should not be used. To be safe, always
* make the first octet a zero (never odd!)
*/

unsigned char mac_addr_fec[8] = { 0x00, 0xcf, 0x52, 0x08, 0xcf, 0x01, 0, 0 };

4. I have put in some check points in the Interniche code ( spesific ifec.c) and the initialzation sequence is as follows:

Preparing device for networking
JAUX - prep_fec()
JAUX - fec_init()
JAUX - fec_hwinit()
JAUX - FEC_reset()
JAUX - fec_link_setup()
JAUX - FECInit()
JAUX - FEC_reset()
Ethernet started, Iface: 0, IP: 192.168.0.99
IP address of : 192.168.0.99

5. I am in the porcess of writing my stack - I will keep you posted


J
0 Kudos
Reply