📄 enc28j60.c
字号:
/********************************************* * vim:sw=8:ts=8:si:et * To use the above modeline in vim you must have "set modeline" in your .vimrc * Author: Guido Socher * Copyright: GPL V2 * http://www.gnu.org/licenses/gpl.html * * Based on the enc28j60.c file from the AVRlib library by Pascal Stang. * For AVRlib See http://www.procyonengineering.com/ * Used with explicit permission of Pascal Stang. * * Title: Microchip ENC28J60 Ethernet Interface Driver * Chip type : ATMEGA88 with ENC28J60 *********************************************/
/*********************************************
* modified: 2007-07-07
* Author : Hotislandn
* Copyright: GPL V2
* http://www.mcuzone.com
* Host chip: AT91SAM7S
**********************************************/
/*********************************************
* modified: 2007-08-08
* Author : awake
* Copyright: GPL V2
* http://www.icdev.com.cn/?2213/
* Host chip: ADUC7026
**********************************************/
#include <LPC2103.H>
//#include <ADuC7026.h>
#define AT_ARM
#ifdef ATMEGA88#include <avr/io.h>#include "avr_compat.h"#include "enc28j60.h"#include "timeout.h"//#define F_CPU 8000000UL // 8 MHz#ifndef ALIBC_OLD#include <util/delay.h>#else#include <avr/delay.h>#endif#endif
#ifdef AT91SAM7S64
#define AT_ARM
#include "AT91SAM7S64.h"
#include "lib_AT91SAM7S64.h"
#endif
#ifdef AT91SAM7S32
#define AT_ARM
#include "AT91SAM7S32.h"
#include "lib_AT91SAM7S32.h"
#endif
#ifdef AT91SAM7S256
#define AT_ARM
#include "AT91SAM7S256.h"
#include "lib_AT91SAM7S256.h"
#endif
#ifdef AT_ARM
#include "enc28j60.h"
//#include "SAM7SDK_BSP.h"
#endif
#define uint8_t unsigned char
#define uint16_t unsigned shortstatic uint8_t Enc28j60Bank;static uint16_t NextPacketPtr;
#ifdef ATMEGA88#define ENC28J60_CONTROL_PORT PORTB#define ENC28J60_CONTROL_DDR DDRB#define ENC28J60_CONTROL_CS 2
#define enc28j60CSinit() ENC28J60_CONTROL_DDR |= (1 << ENC28J60_CONTROL_CS)// set CS to 0 = active#define CSACTIVE ENC28J60_CONTROL_PORT&=~(1<<ENC28J60_CONTROL_CS)// set CS to 1 = passive#define CSPASSIVE ENC28J60_CONTROL_PORT|=(1<<ENC28J60_CONTROL_CS)//#define waitspi() while(!(SPSR&(1<<SPIF)))
#define enc28j60SetSCK()
#define enc28j60HWreset()
#endif
#ifdef AT_ARM
#define ENC_CS_IO (unsigned int)(1 << 31)
#define ENC_RST_IO (unsigned int)(1 << 15)
// use channel 0, for all the peripherals are controled by PIO, not SPI
#define ENC_SPI_CH (0)
#define waitspi()
/*
Send data to slave or receive data from slave
*/
unsigned short SAMspiSend(unsigned char ch, unsigned short data)
{
//unsigned int spib = 0;
//AT91PS_SPI pSPI = AT91C_BASE_SPI;
//ch &= 0x0F;
//while((pSPI->SPI_SR & AT91C_SPI_TDRE) == 0); // Wait for the transfer to complete
//pSPI->SPI_TDR = (ch << 16) | (data & 0xFFFF); // Send the data
//pSPI->SPI_TDR = (data & 0xFFFF); // Send the data
//while((pSPI->SPI_SR & AT91C_SPI_RDRF) == 0); // Wait until the character can be sent
//spib = ((pSPI->SPI_RDR) & 0xFFFF); // Get the data received
//return spib;
// unsigned char data;
//SPITX = data;
// while ((SPISTA & 0x02) != 0x02) ;
// while (!(SPISTA & 0x08)) ;
// data = SPIRX;
// return data;
S0SPDR = data;
while( 0==(S0SPSR&0x80));
data = S0SPDR;
return(data);
}
/*
initialize the contorl logic of /CS pin
*/
static void enc28j60CSinit(void)
{
// AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
// pPIOA->PIO_PER = ENC_CS_IO; // enable PIO of CS-pin
// pPIOA->PIO_SODR = ENC_CS_IO; // set
// pPIOA->PIO_OER = ENC_CS_IO; // output
}
/*
enable enc28j60, /CS = Low
*/
static void CSACTIVE(void)
{
//AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
IOCLR |= (1<<7);
//pPIOA->PIO_CODR = ENC_CS_IO; // clear
}
/*
disable enc28j60, /CS = High
*/
static void CSPASSIVE(void)
{
//AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
IOSET |= (1<<7);
//pPIOA->PIO_SODR = ENC_CS_IO; // set
}
/*
set ENC28J60 SPI SCK freq, MAX 10MHz
*/
static void enc28j60SetSCK(void)
{
// SAMspiSetSCBR(ENC_SPI_CH, CPU_Freq / MAX_SCK_FREQ);
}
void delay_ms(unsigned char ms)
{
unsigned int t1, t2;
//t1 = SAMGetCounter(); // each tick is 0.5ms
//t1 += 2*ms;
//do {
// t2 = SAMGetCounter();
// }while(t2 < t1)
for(t1=0;t1<ms;t1++)
{
for(t2=0;t2<100;t2++)
{
;
}
}
}
void _delay_us(unsigned char us)
{
unsigned char len = 20;
for (;us > 0; us --)
{
for (;len > 0; len --);
len = 20;
}
}
/*
ENC28J60 HW reset
*/
static void enc28j60HWreset(void)
{
// AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
// pPIOA->PIO_PER = ENC_RST_IO; // enable PIO of CS-pin
// pPIOA->PIO_SODR = ENC_RST_IO; // set
// pPIOA->PIO_OER = ENC_RST_IO; // output
// pPIOA->PIO_CODR = ENC_RST_IO; // clear
// delay_ms(10);
// pPIOA->PIO_SODR = ENC_RST_IO; // set
// delay_ms(200);
}
#endif
uint8_t enc28j60ReadOp(uint8_t op, uint8_t address){#ifdef AT_ARM
uint8_t dat = 0;
#endif
CSACTIVE();
#ifdef ATMEGA88 // issue read command SPDR = op | (address & ADDR_MASK); waitspi(); // read data SPDR = 0x00; waitspi();
#endif
#ifdef AT_ARM
dat = op | (address & ADDR_MASK);
SAMspiSend(ENC_SPI_CH, dat);
dat = SAMspiSend(ENC_SPI_CH, 0);
#endif // do dummy read if needed (for mac and mii, see datasheet page 29) if(address & 0x80) {
#ifdef ATMEGA88 SPDR = 0x00; waitspi();
#endif
#ifdef AT_ARM
dat = SAMspiSend(ENC_SPI_CH, 0);
#endif } // release CS CSPASSIVE();
#ifdef ATMEGA88 return(SPDR);
#endif
#ifdef AT_ARM
return dat;
#endif}void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data){
#ifdef AT_ARM
uint8_t dat = 0;
#endif
CSACTIVE();
#ifdef ATMEGA88
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -