Ethernet 4/7
Reading the RevID
At this point we have all the necessary code to change the dates with the controller, so we can read the EREVID register, situated in the 3rd bank, which contains the Chip review number.
In the example proposed, the register value is put on the PORTB, so, regarding the scheme, the RB0 pin would stay connected from INT, and TRISB set at zero.
The alternative, leaving int connected, it can shift PORTB to the left.
void main() {
encInit();
setBank(3);
PORTB = readETH(EREVID);
while (1);
}The completed code is added at this article.
Transmission
The ENC28J60, at the MAC level, it is occupied to generate the Preamble, SFD field, the eventual padding and the FCS; all the rest must be inserted by the software in the transmission buffer. Also, the byte which stays in the first buffer memory location, is a control byte and it isn't really send. Using zero like the value of this byte, are used, for the transmission, the options already imposted in MACON3.
We had defined the transmission buffer in a way that begins at TX_BUF_START address, so the operations to follow for the MAC heading preparation are:
- Arrange the EWRPT registers in a way to point at the TX buffer beginning .
- Sending the WBM command you can begin to write the dates in the buffer (between spiWrite.
- Write the control byte ( for example zero).
- Follow the recipient MAC address, that one of the sender, at last Type/Length field.
The function which performs this operation is MACPutHeader:
void MACPutHeader(MACAddr target, u16 type){
u8 i;
bufSize = sizeof(MAC_Header);
setBank(0);
writeReg(EWRPTL, LOW(TX_BUF_START));
writeReg(EWRPTH, HIGH(TX_BUF_START));
CS = 0;
spiWrite(WBM);
spiWrite(0x00); // usa MACON3
for (i=0;i<6;i++)
spiWrite(target.b[i]);
spiWrite(MY_MAC1);
spiWrite(MY_MAC2);
spiWrite(MY_MAC3);
spiWrite(MY_MAC4);
spiWrite(MY_MAC5);
spiWrite(MY_MAC6);
spiWrite(HIGH(type));
spiWrite(LOW(type));
CS = 1;
}The MAC_Header and MACAddr structures are defined in the file MAC.h:
#define TYPE_ARP 0x0806
#define TYPE_IP 0x0800
typedef struct _MAC_Addr {
u8 b[6];
} MACAddr;
typedef struct _MAC_Header {
MACAddr destMAC;
MACAddr sourceMAC;
u16 type;
} MAC_Header;
So the MAC heading is ready; now can be send to the controller the superior level dates.
After this last operation, the packet is ready to be really send; this result reached with a little instructions:
- Wait until the controller is ready to transmit observing the TXRTS (3) bit of the ECON1 register.
- The ETXND registers are charged with the address of the last byte to send. This address will be TX_BUF_START + bufSize.
- Setting the TXRTS bit begins the transmission.
Because of a problem described in the Errata, if the errors are verified (bit EIR.TXERIF), is necessary to reset the transmission logic, with the TXRST (7) bit of ECON1.
void MACSend(){
setBank(0);
if (readETH(EIR) & 0b10) { // if it was verified an error
BFSReg(ECON1, 0b10000000); //
BFCReg(ECON1, 0b10000000); // reset the TX
}
while(readETH(ECON1) & 0b1000); // wait that is ready to send
writeReg(ETXNDL, LOW(TX_BUF_START + bufSize));
writeReg(ETXNDH, HIGH(TX_BUF_START + bufSize));
BFSReg(ECON1, 0b1000); // send
}
Reception
First of all, to verify if it was received a packet, it is controlled that the EPKTCNT register isn't zero; actually this register maintains the received packets counts, and, once elaborated the packet, is decrement.
The happened reception can be saw through the EIR.RXIF bit, but after the Errata, the value of this bit isn't safe.
The dates received are wrote by the controller in the reception buffer beginning with ERXWRPT address, which in initialization phase is automatically set at zero.
At these addresses the first bytes don't belong to the packet, but there are control byte: the first two contain the address where will be write the next packet; the others aren't so important (consult the datasheet to know more).
Let's explain two new variables, the first one is initialized at zero in encInit:
u16 RdPt; u16 packetStart;
RdPt contains tha address of the next packet, while the packetStart the address of the current packet.
Let's see the methode MACGetHeader:
void MACGetHeader(MAC_Header* header){
u8 buf[6];
packetStart = RdPt; // save RdPt in packetStart
setBank(0);
writeReg(ERDPTL, LOW(RdPt)); //
writeReg(ERDPTH, HIGH(RdPt)); // ERDPT = RdPt
encGetArray(&buf[0], 6); // read the 6 byte control
RdPt = (u16)((u16)buf[0] | ((u16)buf[1] << 8 )); // punter next packet
encGetArray((u8*)header, sizeof(MAC_Header)); // read the MAC heading
header->type = htons(header->type); // swapp the field type
}Like you can see, the first thing that is charged in ERDPT the read packet address (saved in RdPt, initially zero), then are read the control bytes and are saved the new RdPt; al last is read the MAC and saved in header.
Read also:
Ethernet 1/7
Ethernet 2/7
Ethernet 3/7
- Chris's blog
- 1326 reads





Post new comment