void SetGlobalInterrupt( int enabled ) { if( enabled ) SetBitField( EIE, EIE_INTIE ); else ClrBitField( EIE, EIE_INTIE ); }
void SetRXInterrupt( int enabled ) { if( enabled ) SetBitField( EIE, EIE_PKTIE ); else ClrBitField( EIE, EIE_PKTIE ); }
// Enable/disable link status interrupt void SetLinkInterrupt( int enabled ) { if( enabled ) SetBitField( EIE, EIE_LINKIE ); else ClrBitField( EIE, EIE_LINKIE ); }
VOID CPokemonCodec::SetIndvAbility(BYTE bIndex, BYTE bPoint) { if(m_pPokemon == NULL || m_bEncoded || bIndex >= 6) return; if(bPoint >= 0x1F) bPoint = 0x1F; SetBitField(m_pInnateInfo, 0x20UL + bIndex * 5, 5, bPoint); }
VOID CPokemonCodec::SetSkillPointBoost(BYTE bIndex, BYTE bBoost) { if(m_pPokemon == NULL || m_bEncoded) return; bIndex &= 0x03; bBoost &= 0x03; SetBitField((LPBYTE)(m_pBreedInfo) + 0x08, bIndex << 1, 0x02, bBoost); }
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; }
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; }
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); }
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 } }
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); }
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; }