Exemple #1
0
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{
Exemple #2
0
static u08 WritePhyReg(u08 address, u16 data)
{ 
  if (address > 0x14)
    return FALSE;
  
  BankSel(2);

  WriteCtrReg(MIREGADR,address);        // Write address of Phy reg 
  WriteCtrReg(MIWRL,(u08)data);        // lower phy data 
  WriteCtrReg(MIWRH,((u08)(data >>8)));    // Upper phydata

  return TRUE;
}
Exemple #3
0
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;
}
Exemple #4
0
void testMe()
{
  unsigned i;

  printf( "***********************\n" );
  printf( "Clock: %u\n", theclock );
  for( i = 0; i < 6; i ++ )
    printf( "%02X ", pdata[ i ] );
  printf( "\n" );
  BankSel( 3 );
  printf( "%02X %02X %02X %02X %02X %02X\n", ReadMacReg( MAADR1 ),  ReadMacReg( MAADR2 ), ReadMacReg( MAADR3 ), 
    ReadMacReg( MAADR4 ), ReadMacReg( MAADR5 ), ReadMacReg( MAADR6 ) );
  printf( "\n" );
  printf( "Rev=%d\n", ReadETHReg( EREVID ) );
  printf( "***********************\n" );
}
Exemple #5
0
static u16 ReadPhyReg(u08 address)
{
 u16 uiData;
 u08 bytStat;

  BankSel(2);
  WriteCtrReg(MIREGADR,address);    // Write address of phy register to read
  SetBitField(MICMD, MICMD_MIIRD);  // Set rd bit
  do                                  
  {
    bytStat = ReadMacReg(MISTAT);
  }while(bytStat & MISTAT_BUSY);

  ClrBitField(MICMD,MICMD_MIIRD);   // Clear rd bit
  uiData = (u16)ReadMacReg(MIRDL);       // Read low data byte
  uiData |=((u16)ReadMacReg(MIRDH)<<8); // Read high data byte

  return uiData;
}
Exemple #6
0
void initMAC( const u8* bytMacAddress )
{
  pdata = bytMacAddress;
  // Initialize the SPI and the CS pin
  theclock = platform_spi_setup( ENC28J60_SPI_ID, PLATFORM_SPI_MASTER, ENC28J60_SPI_CLOCK, 0, 0, 8 );
  platform_pio_op( ENC28J60_CS_PORT, 1 << ENC28J60_CS_PIN, PLATFORM_IO_PIN_SET );
  platform_pio_op( ENC28J60_CS_PORT, 1 << ENC28J60_CS_PIN, PLATFORM_IO_PIN_DIR_OUTPUT );
#if defined( ENC28J60_RESET_PORT ) && defined( ENC28J60_RESET_PIN )
  platform_pio_op( ENC28J60_RESET_PORT, 1 << ENC28J60_RESET_PIN, PLATFORM_IO_PIN_CLEAR );
  platform_pio_op( ENC28J60_RESET_PORT, 1 << ENC28J60_RESET_PIN, PLATFORM_IO_PIN_DIR_OUTPUT );
  platform_timer_delay( 0, 30000 );
  platform_pio_op( ENC28J60_RESET_PORT, 1 << ENC28J60_RESET_PIN, PLATFORM_IO_PIN_SET );
#endif

  ResetMac();       // erm. Resets the MAC.
                    // setup memory by defining ERXST and ERXND
  platform_timer_delay( 0, 20000 );                    
  BankSel(0);       // select bank 0
  WriteCtrReg(ERXSTL,(u08)( RXSTART & 0x00ff));    
  WriteCtrReg(ERXSTH,(u08)((RXSTART & 0xff00)>> 8));
  WriteCtrReg(ERXNDL,(u08)( RXEND   & 0x00ff));
  WriteCtrReg(ERXNDH,(u08)((RXEND   & 0xff00)>>8));
                    // Make sure Rx Read ptr is at the start of Rx segment
  WriteCtrReg(ERXRDPTL, (u08)( RXSTART & 0x00ff));
  WriteCtrReg(ERXRDPTH, (u08)((RXSTART & 0xff00)>> 8));
  BankSel(1);                             // select bank 1
  WriteCtrReg(ERXFCON,( ERXFCON_UCEN + ERXFCON_CRCEN + ERXFCON_BCEN));

                // Initialise the MAC registers
  BankSel(2);                             // select bank 2
  SetBitField(MACON1, MACON1_MARXEN);     // Enable reception of frames
  WriteCtrReg(MACLCON2, 63);
  WriteCtrReg(MACON3, MACON3_FRMLNEN +    // Type / len field will be checked
                      MACON3_TXCRCEN +    // MAC will append valid CRC
                      MACON3_PADCFG0);    // All small packets will be padded
                      

  SetBitField(MACON4, MACON4_DEFER);      
  WriteCtrReg(MAMXFLL, (u08)( MAXFRAMELEN & 0x00ff));     // set max frame len
  WriteCtrReg(MAMXFLH, (u08)((MAXFRAMELEN & 0xff00)>>8));
  WriteCtrReg(MABBIPG, 0x12);             // back to back interpacket gap. set as per data sheet
  WriteCtrReg(MAIPGL , 0x12);             // non back to back interpacket gap. set as per data sheet
  WriteCtrReg(MAIPGH , 0x0C);

  
            //Program our MAC address
  BankSel(3);              
  WriteCtrReg(MAADR1,bytMacAddress[0]);   
  WriteCtrReg(MAADR2,bytMacAddress[1]);  
  WriteCtrReg(MAADR3,bytMacAddress[2]);
  WriteCtrReg(MAADR4,bytMacAddress[3]);
  WriteCtrReg(MAADR5,bytMacAddress[4]);
  WriteCtrReg(MAADR6,bytMacAddress[5]);

  // Initialise the PHY registes
  WritePhyReg(PHCON1, 0x00);
  WritePhyReg(PHCON2, PHCON2_HDLDIS);
  WriteCtrReg(ECON1,  ECON1_RXEN);     //Enable the chip for reception of packets

  SetBitField(EIE, EIE_INTIE);
  WritePhyReg(PHIE, PHIE_PGEIE|PHIE_PLNKIE);
  ReadPhyReg(PHIR);
}
Exemple #7
0
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
  }
}
Exemple #8
0
void initMAC(unsigned char* deviceMAC) {
    /*Initialize the SPI Module*/
    spiInit();

    /*Execute a Soft Reset to the MAC*/
    ResetMac();

    /*Setup the 8kb Memory space on the ENC28J60
    by defining ERXST and ERXND*/
    BankSel(0);//Select Bank 0
    WriteCtrReg(ERXSTL,(unsigned char)( RXSTART & 0x00ff));
    WriteCtrReg(ERXSTH,(unsigned char)((RXSTART & 0xff00)>> 8));
    WriteCtrReg(ERXNDL,(unsigned char)( RXEND   & 0x00ff));
    WriteCtrReg(ERXNDH,(unsigned char)((RXEND   & 0xff00)>>8));

    /*Set RX Read pointer to start of RX Buffer*/
    WriteCtrReg(ERXRDPTL, (unsigned char)( RXSTART & 0x00ff));
    WriteCtrReg(ERXRDPTH, (unsigned char)((RXSTART & 0xff00)>> 8));

    /*Setup Transmit Buffer*/
    WriteCtrReg(ETXSTL,(unsigned char)( TXSTART & 0x00ff));//Start of buffer
    WriteCtrReg(ETXSTH,(unsigned char)((TXSTART & 0xff00)>>8));
    /*End of buffer will depend on packets,so no point
    hardcoding it*/

    /*Set the RX Filters*/
    BankSel(1);//Select Bank 1
    /*REGISTER 8-1: ERXFCON: RECEIVE FILTER CONTROL REGISTER
    See Page 50 of the datasheet.*/
    WriteCtrReg(ERXFCON,( ERXFCON_UCEN + ERXFCON_CRCEN + ERXFCON_PMEN));

    //---Setup packet filter---
    //This part is taken from Guido Socher's AVR enc28j60 driver.Great Work,that.
    //For broadcast packets we allow only ARP packtets
    //All other packets should be unicast only for our mac (MAADR)
    //The pattern to match on is therefore
    //Type     ETH.DST
    //ARP      BROADCAST
    //06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
    //in binary these poitions are:11 0000 0011 1111
    //This is hex 303F->EPMM0=0x3f,EPMM1=0x30
    WriteCtrReg(EPMM0, 0x3f);
    WriteCtrReg(EPMM1, 0x30);
    WriteCtrReg(EPMCSL,0x39);
    WriteCtrReg(EPMCSH,0xf7);


    /*Initialize the MAC Registers*/
    BankSel(2); // select bank 2
    SetBitField(MACON1, MACON1_MARXEN);// Enable reception of frames
    WriteCtrReg(MACON3, MACON3_FRMLNEN +    // Type / len field will be checked
                MACON3_TXCRCEN +    // MAC will append valid CRC
                MACON3_PADCFG0);    // All small packets will be padded

    WriteCtrReg(MAMXFLL, (unsigned char)( MAXFRAMELEN & 0x00ff));// set max frame len
    WriteCtrReg(MAMXFLH, (unsigned char)((MAXFRAMELEN & 0xff00)>>8));
    WriteCtrReg(MABBIPG, 0x12);// back to back interpacket gap. set as per data sheet
    WriteCtrReg(MAIPGL , 0x12);// non back to back interpacket gap. set as per data sheet
    WriteCtrReg(MAIPGH , 0x0C);


    /*Assign the MAC Address to the chip.*/
    BankSel(3);//Select Bank 3.
    WriteCtrReg(MAADR1,deviceMAC[0]);
    WriteCtrReg(MAADR2,deviceMAC[1]);
    WriteCtrReg(MAADR3,deviceMAC[2]);
    WriteCtrReg(MAADR4,deviceMAC[3]);
    WriteCtrReg(MAADR5,deviceMAC[4]);
    WriteCtrReg(MAADR6,deviceMAC[5]);

    /*Initialise the PHY registers
    REGISTER 11-3: PHCON1: PHY CONTROL REGISTER 1
    See Page 65 of the Datasheet.*/
    WritePhyReg(PHCON1, 0x000);
    /*
    "If using half duplex, the host controller may wish to set
    the PHCON2.HDLDIS bit to prevent automatic
    loopback of the data which is transmitted."
    See Section 6.6 on Page 40 */
    WritePhyReg(PHCON2, PHCON2_HDLDIS);

    /*Enable reception of packets*/
    WriteCtrReg(ECON1,  ECON1_RXEN);
}
Exemple #9
0
unsigned char ReadChipRev(void) {
    BankSel(3);
    return(ReadETHReg(EREVID));
}
Exemple #10
0
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;
}