The file Smc91C9x.fth contains the hardware driver layer for the Standard MicroSystems LAN91C92/4/6 Ethernet controller chips as used on the MPE ARM Development Kit, MPE/Hiden SA1110 StrongBox and other MPE boards. The data sheets for these devices may be found at www.smsc.com and the part number for the MPE board is LAN91C96I, which can be used at 5v or 3.3v.
The controller has 64 8 bit registers organised as four banks of 16.
The code is written for portability rather than speed and uses byte accesses only. This permits the code to be used without change on big and little endian CPUs regardless of the bus interface width (8 or 16 bits).
This code assumes a CPU with byte addressing. A cell addressed machine, e.g. most DSPs, will require considerable changes to the source code for memory buffer transfers.
When operating with fast CPUs note the following:
EC@
and EC!
and the optional EW@
and EW!
16 bit words by default assume that the SMC chip
is memory mapped and that
that the SMC memory area is contiguous. If you have a 16 or 32
bit bus and one or more low address lines are ignored you must
adapt these words yourself to suit your hardware.The following must be defined before the file DRIVERS\SMC91C9x.FTH is compiled.
: const equ ; \ n -- ; -- n
If you are using a standalone target with heads and you want
interactive access to all the registers and bit masks, define
CONST
as CONSTANT
, otherwise by default CONST
is defined as EQU
.
$50000000 const EtherBase \ -- addr
Define the base address of the Ethernet controller.
0 equ SMC16? \ -- flag
If SMC16 is non-zero, the driver will use 16 bit register
accesses where possible, otherwise it will use two 8 bit
accesses. SMC16 should only be set non-zero for little
endian CPUs.
1 equ fastCPU? \ -- n
Set this value false if no software intervention is
required to meet the 400ns timing requirement before and after
changing the pointer register.
0 equ smcDiags? \ -- flag
Set this equate true to compile diagnostic code for
register dumping and so on. False by default.
0 equ eeprom? \ -- flag
Set this equate true if the LAN91C9x has an attached EEPROM
for configuration data storage. False by default.
0 equ GenericIP? \ -- flag
Set this equate true if the Generic IP device structure
defined in ETHERCOM.FTH is required. This is only
required for systems using multiple IP devices in future
releases of PowerNet.
1 equ sniff? \ -- flag
Set this equate true to compile the packet sniffer code,
which can be used to test Ethernet reception.
create EtherAddress \ -- addr
Holds the Ethernet MAC address (six bytes). Note that you
must obtain these from the IEEE (www.ieee.org) or from other
sources.
create IpAddress \ -- addr
Holds the Ethernet IP address (four bytes).
BankSelect |
Offset of bank select register |
TCRL |
Transmit Control Register - lo byte |
TCRH |
Transmit Control Register - hi byte |
TXSTATUS |
Transmit Status Register |
RCR |
Receive Control Register |
MIR |
Memory Information Register |
MCR |
Memory Control Register |
Configl |
Configuration Register - lo byte |
Configh |
Configuration Register - hi byte |
IA0 |
Hardware Address, Ethernet MSB |
IA1 |
Hardware addr |
IA2 |
Hardware addr |
IA3 |
Hardware addr |
IA4 |
Hardware addr |
IA5 |
Hardware addr |
Ctrh |
Control Register - hi byte |
MMU |
Memory management unit cmd reg |
PNR |
Packet number register |
ARR |
Allocation result register. |
Pointerl |
Memory pointer register |
Pointerh |
Memory pointer register |
Datal |
Reg to send packets too... |
Datah |
Reg to send packets too... |
IntStatus |
|
IntMask |
|
RelRx |
MMU Command to release memory from an rx |
RxRd |
SMC Command to read received packet |
TxWr |
SMC Command to write to tx area of ram |
AllocIntMask |
Memory allocated mask |
MaxMsgSize |
Max 802.3 Ether frame size in bytes |
AllocTx |
|
bit0 |
Bitmask |
bit1 |
Bitmask |
bit2 |
Bitmask |
bit3 |
Bitmask |
bit4 |
Bitmask |
bit5 |
Bitmask |
bit6 |
Bitmask |
bit7 |
Bitmask |
EvenTx |
Control byte for tx of even bytes |
OddTx |
Control byte for tx of odd bytes |
RxTask# |
Multi Task ID |
The default code is for a memory-mapped device at base
address EtherBase
.
: ec! \ b offset --
Set an 8 bit register contents to b, in the selected bank.
: ec@ \ offset -- val
Read an 8 bit register in the selected bank.
: ew! \ w offset --
For LITTLE-ENDIAN CPUs only.
Set a 16 bit register contents to w, in the selected bank.
: ew@ \ offset -- val
For LITTLE-ENDIAN CPUs only.
Read a 16 bit register in the selected bank.
: ec! \ val offset --
VFX optimising compilers will probably produce shorter
and faster code by using a compiler macro for EC!
.
: ec@ \ offset -- val
VFX optimising compilers will probably produce shorter
and faster code by using a compiler macro for EC@
.
: ew! \ val offset --
VFX optimising compilers will probably produce shorter
and faster code by using a compiler macro for EW!
.
: ew@ \ offset -- val
VFX optimising compilers will probably produce shorter
and faster code by using a compiler macro for EW@
.
: 400ns \ --
For fast CPUs, use this hardware dependent word to ensure
at least 400ns between back to back Ethernet chip accesses.
This is required for correct operation of the pointer register.
The default version here assumes 4 instructions per iteration
at 5ns per instruction, and the call/return and set up overheads
are ignored. See FASTCPU?
above.
: 400ns \ --
Use this version if your CPU takes at least 400 ns between back
to back Ethernet chip accesses. See FASTCPU?
above.
: SetBank \ bank -- ; bank = 0 to 3
Select the active register bank.
: .bank \ --
Display register contents for currently selected SMC bank.
: .reg \ --
Display contents of all SMC Ethernet Controller's registers
: eISR@ \ -- bmask
Read the bank 2 interrupt status register (IST).
: eMMU! \ cmd --
Send a command to the bank 2 MMU register.
: eTCRl@ \ -- bmask
Read the bank 0 TCRl register.
: EnEtherTx \ --
Enable Ethernet transmission. Selects bank 0.
: eSoftRst \ --
Initiate software reset - needed to clear Tx lock up.
: init-SMC \ --
Initialise SMC chip.
: init-EtherTx \ --
Enable Ethernet TX module.
: init-EtherRx \ --
Enable Ethernet RX module.
: etheradd>CS \ addr --
Store 6 byte Ethernet address into SMC chip from memory buffer.
: InitEther \ --
Perform a full initialisation of the chip, enabling
Rx and Tx, and setting up the Ethernet MAC address
from ETHERADDRESS
.
: EtherLink? \ -- flag
Return true if the Ethernet link is established.
: AllocTxMem \ n -- mask
Allocate n bytes of memory to hold a packet for transmission.
Return the contents of the ARR register, or -1 for a fatal error.
: GetTxMem \ n -- ior
Allocate n bytes of memory to hold a packet for transmission.
: WritePacket \ addr len --
Write an Ethernet frame to chip for transmission.
: IsRx? \ -- t|f
Check if incoming data is present, returning true if a
packet is available for get_ether_pkt
below.
: DiscardRX \ --
Throw away pending input packet due to lack of memory.
: get_ether_pkt \ *dest maxlen -- len
Get pending receive packet to a buffer.
Note that data is valid only when ISRX?
returns true,
so that you must poll with ISRX?
before using
GET_ETHER_PKT
.
: IsTx? \ n -- flag
Return true if a packet of length n can be sent.
: send_ether_pkt \ addr len --
Send packet from supplied buffer.
The word will block until sufficient packet memory is available.
Note that you should read incoming packets regularly, otherwise
it is possible to get into a situation in which SEND_ETHER_PKT
blocks for ever because there is not enough space in the
device for the transmission packet. Theoretically, this should
not happen because 1536 bytes are reserved for transmission,
but ...
: ee! \ word offset --
Write a 16 bit word into the EEPROM at EEPROM address
offset. The EEPROM may not be present in all SMC91C9x
implementations.
: ee@ \ offset -- word
Read a 16 bit word from the EEPROM at EEPROM address
offset. The EEPROM may not be present in all SMC91C9x
implementations.
The code in this section is only compiled if the equate *\fo{GenericIP?) has been defined and is non-zero.
The layout and usage of this structure is defined in the file COMMON\ETHERCOM.FTH.
create IPdevice
' MyInit , \ 0: initialisation
' MyTerm , \ 1: shutdown
' MyRx? , \ 2: receive test
' MyRx \ 3: receive packet
' MyTx? , \ 4: transmit test
' MyTx , \ 5: transmit packet
' MyGetAddr , \ 6: Get device addresses
' MySetAddr , \ 7: Set device addresses
' MySave , \ 8: Save IP device state
: GetAddrs \ -- ipaddr macaddr 0
For Generic I/O IPDGetAddr
function
: SetAddrs \ ipaddr|0 macaddr|0 mode --
Set up the Ethernet MAC and the IP addresses.
At present mode is always 0, but will be used in
future releases to indicate data formats. If
ipaddr or macaddr are zero, the stored data
will not be changed.
create SMCvector \ -- addr
The device vector needed by PowerNet v3+ and
COMMON\ETHERCOM.FTH.
SMCvector constant IPDevice \ -- addr
IPDevice
is the default device name required by
ETHERCOM.FTH. If you have multiple ports, only one
should be named IPDevice
.
This code is only compiled if the equate SNIFF?
is non-zero.
1536 buffer: pbuff \ -- addr
Buffer for SNIFF.
: sniff \ --
Listens to the network and displays all the traffic that
has a broadcast destination or is for this device.
SNIFF
can be used to test reception.