Introduction
Introduction Statistics Contact Development Disclaimer Help
Programming the LAN9221 ethernet controller
(on the Foenix A2560K in C)
I am not a professional programmer and I had never tried to
write anything like a 'device driver' or similar. I was faced
with the challenge to write my 'own' driver for my Foenix
A2560K modern retro machine. It doesn't come with an OS, you
can't run Linux on it. So all you got is the bare machine. And
I needed connectivity, preferably through Ethernet. So what do
you do?
For me, there are 2 important sources of information, of which
one you'll find here. A assembly-wizard I met on the Foenix
Retro Discord (by the screenname of 'gadget') created excellent
Motorola 680x0 assembly code that can read and write to the
controller. That code gave a pretty good insight into the way
the LAN controller should be handled. But..it was assembly code
and it was an extract from real purposed application code, so
not really a reuseable library.
The other resource is, of course, the original datasheet of the
Microchip LAN9221 controller:
The LAN9221 Datasheet
As you can see from the datasheet the LAN9221 has an enormous
array of registers that you must use to control it. The MAC and
PHY modules can not be accessed directly, but need indirect
read/write operations by commands that you have to give through
separate command and data registers for these modules. We'll
get to that later.
The datasheet translates into an extensive header file, in
which you'll recognize much of the datasheet's nomenclature:
The lan9221.h header file
The basics of controlling the 9221 are about reading and writing
its registers. So the first thhin we need to be able to do,
even before we are going to try to initialize the controller, we
need to be able to read and write to its internal registers.
Reading the registers: eth_reg_read()
This should be very straightforward, right? What could be
complicated about reading or writing to a known memory location?
Well, there is one caveat: the endiness of the 32 bits (4 bytes)
that you read or write.
<explain the endiness here>
Now that we know this, writing the registers should be pretty
straightforward:
Writing the registers: eth_reg_write()
Now that we know how to read and write the registers, we are ready
to initialize the module in our Foenix.
To initialize the module, we do the following:
step 1: wait until the module is 'up'
step 2: check the byte-endiness by reading the BYTE_TEST register
check: this register ALWAYS returns 0x87654321
step 3: read the device ID (for fun)
step 4: check the physical connection
The following code-snippet implements this as eth_init():
Initialize controller: eth_init()
Set MAC address (eth_set_mac_address)
You are viewing proxied material from sdf.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.