unsigned int MACRead(unsigned char* packet, unsigned int maxLen){ volatile unsigned int pckLen; static unsigned int nextpckptr = RXSTART; /*Check if Link is Up*/ if(IsLinkUp()==0){ return FALSE; } /*Read EPKTCNT to see if we have any packets in.*/ BankSel(1);//Select Bank 1. if(ReadETHReg(EPKTCNT) == 0){ return 0;//Report that No Proper Packets RX'd. } /*Setup memory pointers to Read in this RX'd packet.*/ BankSel(0); WriteCtrReg(ERDPTL,(unsigned char)( nextpckptr & 0x00ff)); WriteCtrReg(ERDPTH,(unsigned char)((nextpckptr & 0xff00)>>8)); /*Read in the Next Packet Pointer,and the following 32bit Status Vector. See FIGURE 7-3: SAMPLE RECEIVE PACKET LAYOUT on Page 45 of the datasheet.*/ ReadMacBuffer((unsigned char*)&ptrRxStatus.v[0],6); /*Because,Little Endian.*/ nextpckptr = CYSWAP_ENDIAN16(ptrRxStatus.bits.NextPacket); /*Compute actual length of the RX'd Packet.*/ pckLen=CYSWAP_ENDIAN16(ptrRxStatus.bits.ByteCount) - 4; //We take away 4 as that is the CRC if( pckLen > (maxLen-1) ){ pckLen = maxLen; } /*Read the packet only if it was RX'd Okay. We should be checking other flags too,like Length Out of Range, but that one doesnt seem reliable. We need more work and testing here.*/ if(ptrRxStatus.bits.RxOk==0x01){ ReadMacBuffer(packet,pckLen);//Read packet into buffer. } /*Ensure that ERXRDPT is Always ODD! Else Buffer gets corrupted. See No.5 in the Silicon Errata*/ BankSel(0); if ( ((nextpckptr - 1) < RXSTART) || ((nextpckptr-1) > RXEND) ) { /*Free up memory in that 8kb buffer by adjusting the RX Read pointer, since we are done with the packet.*/ WriteCtrReg(ERXRDPTL, (RXEND & 0x00ff)); WriteCtrReg(ERXRDPTH, ((RXEND & 0xff00) >> 8)); }else{
u16 MACRead(u08 * ptrBuffer, u16 maxsize ) { static u16 nextpckptr = RXSTART; RXSTATUS ptrRxStatus; u08 bytPacket; u16 actsize; BankSel(1); bytPacket = ReadETHReg(EPKTCNT); // How many packets have been received if(bytPacket == 0) return bytPacket; // No full packets received BankSel(0); WriteCtrReg(ERDPTL,(u08)(nextpckptr & 0x00ff)); //write this value to read buffer ptr WriteCtrReg(ERDPTH,(u08)((nextpckptr & 0xff00)>>8)); ReadMacBuffer((u08*)&ptrRxStatus.v[0],6); // read next packet ptr + 4 status bytes nextpckptr = ptrRxStatus.bits.NextPacket; actsize = ptrRxStatus.bits.ByteCount; if( actsize > maxsize ) actsize = maxsize; ReadMacBuffer(ptrBuffer,actsize); // read packet into buffer // ptrBuffer should now contain a MAC packet BankSel(0); WriteCtrReg(ERXRDPTL,ptrRxStatus.v[0]); // free up ENC memory my adjustng the Rx Read ptr WriteCtrReg(ERXRDPTH,ptrRxStatus.v[1]); // decrement packet counter SetBitField(ECON2, ECON2_PKTDEC); return actsize; }
u16 MACWrite(u08 * ptrBuffer, u16 ui_Len) { volatile u16 address = TXSTART; u08 bytControl; bytControl = 0x00; BankSel(0); // select bank 0 WriteCtrReg(ETXSTL,(u08)( TXSTART & 0x00ff)); // write ptr to start of Tx packet WriteCtrReg(ETXSTH,(u08)((TXSTART & 0xff00)>>8)); WriteCtrReg(EWRPTL,(u08)( TXSTART & 0x00ff)); // Set write buffer to point to start of Tx Buffer WriteCtrReg(EWRPTH,(u08)((TXSTART & 0xff00)>>8)); WriteMacBuffer(&bytControl,1); // write per packet control byte address++; address+=WriteMacBuffer(ptrBuffer, ui_Len); // write packet. Assume correct formating src, dst, type + data WriteCtrReg(ETXNDL, (u08)( address & 0x00ff)); // Tell MAC when the end of the packet is WriteCtrReg(ETXNDH, (u08)((address & 0xff00)>>8)); ClrBitField(EIR,EIR_TXIF); //SetBitField(EIE, EIE_TXIE |EIE_INTIE); ERRATAFIX; SetBitField(ECON1, ECON1_TXRTS); // begin transmitting; do { // [TODO] add timers here or make packet sending completely asynchronous }while (!(ReadETHReg(EIR) & (EIR_TXIF))); // kill some time. Note: Nice place to block? ClrBitField(ECON1, ECON1_TXRTS); BankSel(0); //read tx status bytes address++; // increment ptr to address to start of status struc WriteCtrReg(ERDPTL, (u08)( address & 0x00ff)); // Setup the buffer read ptr to read status struc WriteCtrReg(ERDPTH, (u08)((address & 0xff00)>>8)); ReadMacBuffer(&TxStatus.v[0],7); if (ReadETHReg(ESTAT) & ESTAT_TXABRT) // did transmission get interrupted? { if (TxStatus.bits.LateCollision) { ClrBitField(ECON1, ECON1_TXRTS); SetBitField(ECON1, ECON1_TXRTS); ClrBitField(ESTAT,ESTAT_TXABRT | ESTAT_LATECOL); } ClrBitField(EIR, EIR_TXERIF | EIR_TXIF); ClrBitField(ESTAT,ESTAT_TXABRT); //printf( " NOT SENT for len=%d\n", ui_Len ); return FALSE; // packet transmit failed. Inform calling function } // calling function may inquire why packet failed by calling [TO DO] function else { //printf( "SENT\n" ); return TRUE; // all fan dabby dozy } }
unsigned char MACWrite(unsigned char* packet, unsigned int len) { unsigned char bytControl=0x00; /*Configure TX Buffer Pointers*/ BankSel(0);// select bank 0 /*Buffer write ptr to start of Tx packet*/ WriteCtrReg(ETXSTL,(unsigned char)( TXSTART & 0x00ff)); WriteCtrReg(ETXSTH,(unsigned char)((TXSTART & 0xff00)>>8)); /*Set write buffer pointer to point to start of Tx Buffer*/ WriteCtrReg(EWRPTL,(unsigned char)( TXSTART & 0x00ff)); WriteCtrReg(EWRPTH,(unsigned char)((TXSTART & 0xff00)>>8)); /*Write the Per Packet Control Byte See FIGURE 7-1: FORMAT FOR PER PACKET CONTROL BYTES on Page 41 of the datasheet */ WriteMacBuffer(&bytControl,1); /*Write the packet into the ENC's buffer*/ WriteMacBuffer(packet, len); /*Tell MAC when the end of the packet is*/ WriteCtrReg(ETXNDL, (unsigned char)( (len+TXSTART+1) & 0x00ff)); WriteCtrReg(ETXNDH, (unsigned char)(((len+TXSTART+1) & 0xff00)>>8)); /*We would like to enable Interrupts on Packet TX complete.*/ ClrBitField(EIR,EIR_TXIF); SetBitField(EIE, EIE_TXIE |EIE_INTIE); /*Macro for Silicon Errata to do with Transmit Logic Reset. Silicon Errata No.12 as per Latest Errata doc for ENC28J60 See http://ww1.microchip.com/downloads/en/DeviceDoc/80349c.pdf */ ERRATAFIX; /*Send that Packet!*/ SetBitField(ECON1, ECON1_TXRTS); /*Wait for the Chip to finish the TX,and read the TX interrrupt bit to check the same.*/ do {} while (!(ReadETHReg(EIR) & (EIR_TXIF))); // kill some time. Note: Nice place to block? // kill some time. Note: Nice place to block? /*Clear TXRTS,since the packet has been TX'd.*/ ClrBitField(ECON1, ECON1_TXRTS); /*We will now attempt to read the TX Status Vectors. See TABLE 7-1: TRANSMIT STATUS VECTORS on Page 43 of the datasheet.*/ BankSel(0); /*Because,that control byte.*/ len++; /*Configure the buffer read ptr to read status structure*/ WriteCtrReg(ERDPTL, (unsigned char)( len & 0x00ff)); WriteCtrReg(ERDPTH, (unsigned char)((len & 0xff00)>>8)); /*Read In the TX Status Vectors*/ /*Note: Use these for debugging.Really useful.*/ ReadMacBuffer(&TxStatus.v[0],7); /*Read TX status vectors to see if TX was interrupted.*/ if (ReadETHReg(ESTAT) & ESTAT_TXABRT) { if (TxStatus.bits.LateCollision) { ClrBitField(ECON1, ECON1_TXRTS);//Toggle the TXRTS SetBitField(ECON1, ECON1_TXRTS); ClrBitField(ESTAT,ESTAT_TXABRT | ESTAT_LATECOL);//Clear the Late Collision Bit. } ClrBitField(EIR, EIR_TXERIF | EIR_TXIF);//Clear the Interrupt Flags. ClrBitField(ESTAT,ESTAT_TXABRT);//Clear the Abort Flag. return FALSE;//Report a Failed Packet TX. } else { return TRUE;//Packet Sent Okay! :-) } return TRUE; }