2369 views|2 replies

8

Posts

0

Resources
The OP
 

stm32f407 driver enc28j60 [Copy link]

I'm adjusting the driver of enc28j60 recently. It was successfully driven on f103 board before. Now it is transplanted to f407. I changed the library of f407, spi interface function and pin definition, and almost didn't change enc28j60.c and .h files. But I can't send and receive data. After debugging, I found that there was a problem with spi reading and writing. When writing 6 bytes of mac, only one was correct, and the others were all 0. I've been adjusting it for 2 days. I've tried changing different spi frequency division coefficients, but it still doesn't work. I would like to ask all the experts how to solve this problem. I hope you can give me some advice. The following is the relevant code: This is the initialization u8 of enc28j60 ENC28J60_Init(void) { volatile u8 version=0; u16 retry=0; u32 temp=0; SPI2_Init(); delay_ms(20); EXTI10_INT_Config(); EXTI_ClearITPendingBit(EXTI_Line10); SPI1_SetSpeed(SPI_BaudRatePrescaler_64); //SPI2 SCK frequency //Initialize MAC address //temp=*(vu32*)(0x1FFFF7E8); //Get the first 24 bits of the unique ID of STM32 as the last three bytes of the MAC address enc28j60_dev.macaddr[0]=0x11; enc28j60_dev.macaddr[1]=0x22; enc28j60_dev.macaddr[2]=0x33; enc28j60_dev.macaddr[3]=0x44; enc28j60_dev.macaddr[4]=0x55; enc28j60_dev.macaddr[5]=0x66; ENC28J60_RST=0; //Reset ENC28J60 delay_ms(20); ENC28J60_RST=1; //Reset ends delay_ms(20); ENC28J60_Write_Op(ENC28J60_SOFT_RESET,0,ENC28J60_SOFT_RESET); //Software reset while(!(ENC28J60_Read(ESTAT)&ESTAT_CLKRDY)&&retry<250) //Wait for the clock to stabilize { retry++; delay_ms(1); } if(retry>=250)return 1; //ENC28J60 initialization failed version=ENC28J60_Get_EREVID(); //Get the version number of ENC28J60 enc28j60_dev.NextPacketPtr=RXSTART_INIT; //Set the receive start byte ENC28J60_Write(ERXSTL,RXSTART_INIT&0XFF); //Set the receive buffer start address low 8 bits ENC28J60_Write(ERXSTH,RXSTART_INIT>>8); //Set the high 8 bits of the start address of the receive buffer //Set the receive byte ENC28J60_Write(ERXNDL,RXSTOP_INIT&0XFF); ENC28J60_Write(ERXNDH,RXSTOP_INIT>>8); //Set the send start byte ENC28J60_Write(ETXSTL,TXSTART_INIT&0XFF); ENC28J60_Write(ETXSTH,TXSTART_INIT>>8); //Set the send end byte ENC28J60_Write(ETXNDL,TXSTOP_INIT&0XFF); ENC28J60_Write(ETXNDH,TXSTOP_INIT>>8); ENC28J60_Write(ERXRDPTL,RXSTART_INIT&0XFF); ENC28J60_Write(ERXRDPTH,RXSTART_INIT>>8); //ENC28J60_Write(ERXFCON,ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN); ENC28J60_Write(ERXFCON,0); ENC28J60_Write(EPMM0,0X3F); ENC28J60_Write(EPMM1 ,0X30); ENC28J60_Write(EPMCSL,0Xf9); ENC28J60_Write(EPMCSH,0Xf7); ENC28J60_Write(MACON1,MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); ENC28J60_Write(MACON3,MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN|MACON3_FULDPX); // Maximum frame length 1518 ENC28J60_Write(MAMXFLL,MAX_FRAMELEN&0XFF); ENC28J60_Write(MAMXFLH,MAX_FRAMELEN>>8); ENC28J60_W rite(MABBIPG,0x15); ENC28J60_Write(MAIPGL,0x12); ENC28J60_Write(MAIPGH,0x0C); //Set the MAC address ENC28J60_Write(MAADR5,enc28j60_dev.macaddr[0]); ENC28J60_Write(MAADR4,enc28j60_dev.macaddr[1 ]); ENC28J60_Write(MAADR3,enc28j60_dev.macaddr[2]); ENC28J60_Write(MAADR2,enc28j60_dev.macaddr[3]); ENC28J60_Write(MAADR1,enc28j60_dev.macaddr[5]); ENC28J60_Write(MAADR0,enc28j60_dev.macaddr[4]); //Configure PHY to full duplex LEDB to source current ENC28J60_PHY_Write(PHCON1,PHCON1_PDPXMD); ENC28J60_PHY_Write(PHCON2,PHCON2_HDLDIS); ENC28J60_Set_Bank(ECON1); ENC28J60_Write_Op(ENC28J60_BIT_FIELD_SET,EIE,EIE_INTIE|EIE_PKTIE|EIE_TXIE|EIE_TXERIE|EIE_RXERIE); ENC28J60_Write_Op(ENC28J60_BIT_FIELD_SET,ECON1,ECON1_RXEN); // printf("ENC28J60 Duplex :%s\r\n",ENC28J60_Get_Duplex()?"Full Duplex":"Half Duplex");        //获取双工方式
        return 0;
}


void SPI2_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
          SPI_InitTypeDef  SPI_InitStructure;

       
//enable portA clock and portB clock
//enable spi1 clock

       
        RCC->AHB1ENR |= 7;        //portA,B,C clock enable
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);//SPI2
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;                               
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                  
                GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;  
        GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);                   
                       
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //debug for cs cannot pulldown
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;       
        GPIO_Init(GPIOC, &GPIO_InitStructure);                                       
  GPIO_SetBits(GPIOC,GPIO_Pin_2);                
          
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;      
   GPIO_Init(GPIOB, &GPIO_InitStructure);
       
       
GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);  
GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);


RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,DISABLE);

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
//SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
//SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
//SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_BaudRatePrescaler=0;

SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);   
SPI_Cmd(SPI2, ENABLE);


SPI2_ReadWriteByte(0xff);


}

u8 SPI2_ReadWriteByte(u8 TxData)
{               
    u8 retry=0;
#if 1
SPI2->DR = TxData;      
while ((SPI2->SR & SPI_I2S_FLAG_RXNE) == 0x00)
{
                //        retry++;
        //        if(retry>200)return 0;
}
return SPI2->DR;
#else
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET);  
SPI_SendData(SPI2, TxData);                             
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_RXNE) == RESET);
return SPI_ReceiveData(SPI2);                           
#endif

       
}


代码参考了原子的103板子的代码C clock enable
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);//SPI2
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;                               
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                  
                GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;  
        GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);                   
                       
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //debug for cs cannot pulldown
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;       
        GPIO_Init(GPIOC, &GPIO_InitStructure);                                       
  GPIO_SetBits(GPIOC,GPIO_Pin_2);                
          
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;      
   GPIO_Init(GPIOB, &GPIO_InitStructure);
       
       
GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);  
GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);


RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,DISABLE);

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
//SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
//SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
//SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_BaudRatePrescaler=0;

SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);   
SPI_Cmd(SPI2, ENABLE);


SPI2_ReadWriteByte(0xff);


}

u8 SPI2_ReadWriteByte(u8 TxData)
{               
    u8 retry=0;
#if 1
SPI2->DR = TxData;      
while ((SPI2->SR & SPI_I2S_FLAG_RXNE) == 0x00)
{
                //        retry++;
        //        if(retry>200)return 0;
}
return SPI2->DR;
#else
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET);  
SPI_SendData(SPI2, TxData);                             
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_RXNE) == RESET);
return SPI_ReceiveData(SPI2);                           
#endif

       
}


代码参考了原子的103板子的代码C clock enable
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);//SPI2
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;                               
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                  
                GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;  
        GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);                   
                       
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //debug for cs cannot pulldown
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;       
        GPIO_Init(GPIOC, &GPIO_InitStructure);                                       
  GPIO_SetBits(GPIOC,GPIO_Pin_2);                
          
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;      
   GPIO_Init(GPIOB, &GPIO_InitStructure);
       
       
GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);  
GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);


RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,DISABLE);

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
//SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
//SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
//SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_BaudRatePrescaler=0;

SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);   
SPI_Cmd(SPI2, ENABLE);


SPI2_ReadWriteByte(0xff);


}

u8 SPI2_ReadWriteByte(u8 TxData)
{               
    u8 retry=0;
#if 1
SPI2->DR = TxData;      
while ((SPI2->SR & SPI_I2S_FLAG_RXNE) == 0x00)
{
                //        retry++;
        //        if(retry>200)return 0;
}
return SPI2->DR;
#else
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET);  
SPI_SendData(SPI2, TxData);                             
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_RXNE) == RESET);
return SPI_ReceiveData(SPI2);                           
#endif

       
}


代码参考了原子的103板子的代码GPIO_Mode = GPIO_Mode_AF;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;      
   GPIO_Init(GPIOB, &GPIO_InitStructure);
       
       
GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);  
GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);


RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,DISABLE);

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
//SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
//SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
//SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_BaudRatePrescaler=0;

SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);   
SPI_Cmd(SPI2, ENABLE);


SPI2_ReadWriteByte(0xff);


}

u8 SPI2_ReadWriteByte(u8 TxData)
{               
    u8 retry=0;
#if 1
SPI2->DR = TxData;      
while ((SPI2->SR & SPI_I2S_FLAG_RXNE) == 0x00)
{
                //        retry++;
        //        if(retry>200)return 0;
}
return SPI2->DR;
#else
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET);  
SPI_SendData(SPI2, TxData);                             
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_RXNE) == RESET);
return SPI_ReceiveData(SPI2);                           
#endif

       
}


代码参考了原子的103板子的代码GPIO_Mode = GPIO_Mode_AF;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;      
   GPIO_Init(GPIOB, &GPIO_InitStructure);
       
       
GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);  
GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);


RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,DISABLE);

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
//SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
//SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
//SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_BaudRatePrescaler=0;

SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);   
SPI_Cmd(SPI2, ENABLE);


SPI2_ReadWriteByte(0xff);


}

u8 SPI2_ReadWriteByte(u8 TxData)
{               
    u8 retry=0;
#if 1
SPI2->DR = TxData;      
while ((SPI2->SR & SPI_I2S_FLAG_RXNE) == 0x00)
{
                //        retry++;
        //        if(retry>200)return 0;
}
return SPI2->DR;
#else
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET);  
SPI_SendData(SPI2, TxData);                             
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_RXNE) == RESET);
return SPI_ReceiveData(SPI2);                           
#endif

       
}


代码参考了原子的103板子的代码ENABLE);


SPI2_ReadWriteByte(0xff);


}

u8 SPI2_ReadWriteByte(u8 TxData)
{               
    u8 retry=0;
#if 1
SPI2->DR = TxData;      
while ((SPI2->SR & SPI_I2S_FLAG_RXNE) == 0x00)
{
                //        retry++;
        //        if(retry>200)return 0;
}
return SPI2->DR;
#else
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET);  
SPI_SendData(SPI2, TxData);                             
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_RXNE) == RESET);
return SPI_ReceiveData(SPI2);                           
#endif

       
}


代码参考了原子的103板子的代码ENABLE);


SPI2_ReadWriteByte(0xff);


}

u8 SPI2_ReadWriteByte(u8 TxData)
{               
    u8 retry=0;
#if 1
SPI2->DR = TxData;      
while ((SPI2->SR & SPI_I2S_FLAG_RXNE) == 0x00)
{
                //        retry++;
        //        if(retry>200)return 0;
}
return SPI2->DR;
#else
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET);  
SPI_SendData(SPI2, TxData);                             
while (SPI_GetFlagStatus(SPI2, SPI_FLAG_RXNE) == RESET);
return SPI_ReceiveData(SPI2);                           
#endif

       
}


代码参考了原子的103板子的代码




This post is from stm32/stm8

Latest reply

[attach]407429[/attach] #include "ENC28J60.h" #include "spi.h" #include "lcd.h" static uint8_t Enc28j60Bank; static uint16_t gNextPacketPtr; static uint8_t erxfcon; unsigned char ENC28J60_SendByte(unsigned char dt) {         while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);         SPI_I2S_SendData(SPI1, dt);         while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);         return SPI_I2S_ReceiveData(SPI1); } uint8_t enc28j60ReadOp(uint8_t op, uint8_t address) {                 uint8_t temp;         enableChip;         // issue read command         ENC28J60_SendByte(op | (address & ADDR_MASK));         temp = ENC28J60_SendByte(0xFF);         if (address & 0x80)             temp = ENC28J60_SendByte(0xFF);         // release CS         disableChip;         return temp; } void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data) {     enableChip;     ENC28J60_SendByte(op | (address & ADDR_MASK));     ENC28J60_SendByte(data);     disableChip; } void enc28j60PowerDown() { enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN); while(enc28j60Read(ESTAT) & ESTAT_RXBUSY); while(enc28j60Read(ECON1) & ECON1_TXRTS); enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV); } void enc28j60PowerUp() { enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV); while(!enc28j60Read(ESTAT) & ESTAT_CLKRDY); } void enc28j60ReadBuffer(uint16_t len, uint8_t* data) {     enableChip;     ENC28J60_SendByte(ENC28J60_READ_BUF_MEM);     while (len--) {         *data++ = ENC28J60_SendByte(0x00);     }     disableChip;     // Remove next line suggested by user epam - not needed //    *data='\0'; } static uint16_t enc28j60ReadBufferWord() {     uint16_t result;     enc28j60ReadBuffer(2, (uint8_t*) &result);     return result; } void enc28j60WriteBuffer(uint16_t len, uint8_t* data) {     enableChip;     ENC28J60_SendByte(ENC28J60_WRITE_BUF_MEM);     while (len--)         ENC28J60_SendByte(*data++);     disableChip; } void enc28j60SetBank(uint8_t address) {     if ((address & BANK_MASK) != Enc28j60Bank) {         enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_BSEL1|ECON1_BSEL0);         Enc28j60Bank = address & BANK_MASK;         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, Enc28j60Bank>>5);     } } uint8_t enc28j60Read(uint8_t address) {         // set the bank         enc28j60SetBank(address);         // do the read         return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address); } void enc28j60WriteWord(uint8_t address, uint16_t data) {     enc28j60Write(address, data & 0xff);     enc28j60Write(address + 1, data >> 8); } // read upper 8 bits uint16_t enc28j60PhyReadH(uint8_t address) {         // Set the right address and start the register read operation         enc28j60Write(MIREGADR, address);         enc28j60Write(MICMD, MICMD_MIIRD);         delay_us(15);         // wait until the PHY read completes         while(enc28j60Read(MISTAT) & MISTAT_BUSY);         // reset reading bit         enc28j60Write(MICMD, 0x00);                 return (enc28j60Read(MIRDH)); } void enc28j60Write(uint8_t address, uint8_t data) {         // set the bank         enc28j60SetBank(address);         // do the write         enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data); } void enc28j60PhyWrite(uint8_t address, uint16_t data) {         // set the PHY register address         enc28j60Write(MIREGADR, address);         // write the PHY data         enc28j60Write(MIWRL, data);         enc28j60Write(MIWRH, data>>8);         // wait until the PHY write completes         while(enc28j60Read(MISTAT) & MISTAT_BUSY){                 delay_us(15);         } } /* static void enc28j60PhyWriteWord(byte address, word data) {     enc28j60Write(MIREGADR, address);     //enc28j60WriteByte(MIREGADR, address);     enc28j60WriteWord(MIWRL, data);     while (enc28j60ReadByte(MISTAT) & MISTAT_BUSY)         ; } */ void enc28j60clkout(uint8_t clk) {         //setup clkout: 2 is 12.5MHz:         enc28j60Write(ECOCON, clk & 0x7); } void enc28j60Init( uint8_t* macaddr ) {         enableChip; // ss=0         // perform system reset         enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);         delay_ms(50);         // check CLKRDY bit to see if reset is complete         // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.         //while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));         // do bank 0 stuff         // initialize receive buffer         // 16-bit transfers, must write low byte first         // set receive buffer start address         gNextPacketPtr = RXSTART_INIT;         // Rx start         enc28j60WriteWord(ERXSTL, RXSTART_INIT);         // set receive pointer address         enc28j60WriteWord(ERXRDPTL, RXSTART_INIT);         // RX end         enc28j60WriteWord(ERXNDL, RXSTOP_INIT);         // TX start         enc28j60WriteWord(ETXSTL, TXSTART_INIT);         // TX end         enc28j60WriteWord(ETXNDL, TXSTOP_INIT);         // do bank 1 stuff, packet filter:         // 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         //enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);         //Change to add ERXFCON_BCEN recommended by epam         //enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_BCEN);         erxfcon =  ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_BCEN;         enc28j60Write(ERXFCON, erxfcon );         enc28j60WriteWord(EPMM0, 0x303f);         enc28j60WriteWord(EPMCSL, 0xf7f9);         //         // do bank 2 stuff         // enable MAC receive         enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);         // bring MAC out of reset         enc28j60Write(MACON2, 0x00);         // enable automatic padding to 60bytes and CRC operations         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);  //|MACON3_FULDPX);         // set inter-frame gap (non-back-to-back)         enc28j60WriteWord(MAIPGL, 0x0C12);         // set inter-frame gap (back-to-back)         enc28j60Write(MABBIPG, 0x12);         // Set the maximum packet size which the controller will accept         // Do not send packets longer than MAX_FRAMELEN:         enc28j60WriteWord(MAMXFLL, MAX_FRAMELEN);                // do bank 3 stuff         // write MAC address         // NOTE: MAC address in ENC28J60 is byte-backward         enc28j60Write(MAADR5, macaddr[0]);         enc28j60Write(MAADR4, macaddr[1]);         enc28j60Write(MAADR3, macaddr[2]);         enc28j60Write(MAADR2, macaddr[3]);         enc28j60Write(MAADR1, macaddr[4]);         enc28j60Write(MAADR0, macaddr[5]);         // no loopback of transmitted frames         enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS);         // switch to bank 0         enc28j60SetBank(ECON1);         // enable interrutps         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);         // enable packet reception         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);                 LCD_String(20,80,"Mac Init",GREEN); } // read the revision of the chip: uint8_t enc28j60getrev(void) {         uint8_t rev;         rev=enc28j60Read(EREVID);         // microchip forgot to step the number on the silcon when they         // released the revision B7. 6 is now rev B7. We still have         // to see what they do when they release B8. At the moment         // there is no B8 out yet         if (rev>5) rev++;         return(rev); } // A number of utility functions to enable/disable broadcast and multicast bits void enc28j60EnableBroadcast( void ) {         erxfcon |= ERXFCON_BCEN;         enc28j60Write(ERXFCON, erxfcon); } void enc28j60DisableBroadcast( void ) {         erxfcon &= (0xff ^ ERXFCON_BCEN);         enc28j60Write(ERXFCON, erxfcon); } void enc28j60EnableMulticast( void ) {         erxfcon |= ERXFCON_MCEN;         enc28j60Write(ERXFCON, erxfcon); } void enc28j60DisableMulticast( void ) {         erxfcon &= (0xff ^ ERXFCON_MCEN);         enc28j60Write(ERXFCON, erxfcon); } // link status uint8_t enc28j60linkup(void) {         // bit 10 (= bit 3 in upper reg)         return(enc28j60PhyReadH(PHSTAT2) && 4); } void enc28j60PacketSend(uint16_t len, uint8_t* packet) {         // Check no transmit in progress         while (enc28j60ReadOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_TXRTS)         {                 // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.                 if( (enc28j60Read(EIR) & EIR_TXERIF) ) {                         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);                         enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);                 }         }         // Set the write pointer to start of transmit buffer area         enc28j60WriteWord(EWRPTL, TXSTART_INIT);         // Set the TXND pointer to correspond to the packet size given         enc28j60WriteWord(ETXNDL, (TXSTART_INIT+len));         // write per-packet control byte (0x00 means use macon3 settings)         enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);         // copy the packet into the transmit buffer         enc28j60WriteBuffer(len, packet);         // send the contents of the transmit buffer onto the network         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);         // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12. } // just probe if there might be a packet //uint8_t enc28j60hasRxPkt(void) //{ //       return enc28j60ReadByte(EPKTCNT) > 0; //} // Gets a packet from the network receive buffer, if one is available. // The packet will by headed by an ethernet header. //      maxlen  The maximum acceptable length of a retrieved packet. //      packet  Pointer where packet data should be stored. // Returns: Packet length in bytes if a packet was retrieved, zero otherwise. uint16_t enc28j60PacketReceive(uint16_t maxlen, uint8_t* packet) {                 uint16_t rxstat;         uint16_t len;         // check if a packet has been received and buffered         //if( !(enc28j60Read(EIR) & EIR_PKTIF) ){         // The above does not work. See Rev. B4 Silicon Errata point 6.         if( enc28j60Read(EPKTCNT) ==0 ){                 return(0);         }         // Set the read pointer to the start of the received packet         enc28j60WriteWord(ERDPTL, gNextPacketPtr);         //enc28j60Write(ERDPTL, (gNextPacketPtr &0xFF));         //enc28j60Write(ERDPTH, (gNextPacketPtr)>>8);         // read the next packet pointer         gNextPacketPtr  = enc28j60ReadBufferWord();         //gNextPacketPtr  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);         //gNextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)8);         } else {                 enc28j60WriteWord(ERXRDPTL, (gNextPacketPtr-1));                 //enc28j60Write(ERXRDPTL, (gNextPacketPtr-1)&0xFF);                 //enc28j60Write(ERXRDPTH, (gNextPacketPtr-1)>>8);         }         // decrement the packet counter indicate we are done with this packet         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);         return(len); }   Details Published on 2019-3-27 22:39
 

396

Posts

4

Resources
2
 


#include "ENC28J60.h"
#include "spi.h"
#include "lcd.h"
static uint8_t Enc28j60Bank;
static uint16_t gNextPacketPtr;
static uint8_t erxfcon;


unsigned char ENC28J60_SendByte(unsigned char dt)
{
        while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

        SPI_I2S_SendData(SPI1, dt);

        while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

        return SPI_I2S_ReceiveData(SPI1);
}

uint8_t enc28j60ReadOp(uint8_t op, uint8_t address)
{
                uint8_t temp;
        enableChip;
        // issue read command
        ENC28J60_SendByte(op | (address & ADDR_MASK));
        temp = ENC28J60_SendByte(0xFF);
        if (address & 0x80)
            temp = ENC28J60_SendByte(0xFF);

        // release CS
        disableChip;
        return temp;
}

void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data)
{
    enableChip;
    ENC28J60_SendByte(op | (address & ADDR_MASK));
    ENC28J60_SendByte(data);
    disableChip;
}

void enc28j60PowerDown() {
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN);
while(enc28j60Read(ESTAT) & ESTAT_RXBUSY);
while(enc28j60Read(ECON1) & ECON1_TXRTS);
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV);
}

void enc28j60PowerUp() {
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV);
while(!enc28j60Read(ESTAT) & ESTAT_CLKRDY);
}


void enc28j60ReadBuffer(uint16_t len, uint8_t* data)
{
    enableChip;
    ENC28J60_SendByte(ENC28J60_READ_BUF_MEM);
    while (len--) {
        *data++ = ENC28J60_SendByte(0x00);
    }
    disableChip;
    // Remove next line suggested by user epam - not needed
//    *data='\0';
}

static uint16_t enc28j60ReadBufferWord() {
    uint16_t result;
    enc28j60ReadBuffer(2, (uint8_t*) &result);
    return result;
}


void enc28j60WriteBuffer(uint16_t len, uint8_t* data)
{
    enableChip;
    ENC28J60_SendByte(ENC28J60_WRITE_BUF_MEM);
    while (len--)
        ENC28J60_SendByte(*data++);

    disableChip;
}

void enc28j60SetBank(uint8_t address)
{
    if ((address & BANK_MASK) != Enc28j60Bank) {
        enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_BSEL1|ECON1_BSEL0);
        Enc28j60Bank = address & BANK_MASK;
        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, Enc28j60Bank>>5);
    }
}

uint8_t enc28j60Read(uint8_t address)
{
        // set the bank
        enc28j60SetBank(address);
        // do the read
        return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address);
}

void enc28j60WriteWord(uint8_t address, uint16_t data) {
    enc28j60Write(address, data & 0xff);
    enc28j60Write(address + 1, data >> 8);
}

// read upper 8 bits
uint16_t enc28j60PhyReadH(uint8_t address)
{
        // Set the right address and start the register read operation
        enc28j60Write(MIREGADR, address);
        enc28j60Write(MICMD, MICMD_MIIRD);
        delay_us(15);

        // wait until the PHY read completes
        while(enc28j60Read(MISTAT) & MISTAT_BUSY);

        // reset reading bit
        enc28j60Write(MICMD, 0x00);
       
        return (enc28j60Read(MIRDH));
}


void enc28j60Write(uint8_t address, uint8_t data)
{
        // set the bank
        enc28j60SetBank(address);
        // do the write
        enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data);
}


void enc28j60PhyWrite(uint8_t address, uint16_t data)
{
        // set the PHY register address
        enc28j60Write(MIREGADR, address);
        // write the PHY data
        enc28j60Write(MIWRL, data);
        enc28j60Write(MIWRH, data>>8);
        // wait until the PHY write completes
        while(enc28j60Read(MISTAT) & MISTAT_BUSY){
                delay_us(15);
        }
}
/*
static void enc28j60PhyWriteWord(byte address, word data) {
    enc28j60Write(MIREGADR, address);
    //enc28j60WriteByte(MIREGADR, address);
    enc28j60WriteWord(MIWRL, data);
    while (enc28j60ReadByte(MISTAT) & MISTAT_BUSY)
        ;
}
*/
void enc28j60clkout(uint8_t clk)
{
        //setup clkout: 2 is 12.5MHz:
        enc28j60Write(ECOCON, clk & 0x7);
}

void enc28j60Init( uint8_t* macaddr )
{
        enableChip; // ss=0

        // perform system reset
        enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
        delay_ms(50);
        // check CLKRDY bit to see if reset is complete
        // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
        //while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));
        // do bank 0 stuff
        // initialize receive buffer
        // 16-bit transfers, must write low byte first
        // set receive buffer start address
        gNextPacketPtr = RXSTART_INIT;
        // Rx start
        enc28j60WriteWord(ERXSTL, RXSTART_INIT);
        // set receive pointer address
        enc28j60WriteWord(ERXRDPTL, RXSTART_INIT);
        // RX end
        enc28j60WriteWord(ERXNDL, RXSTOP_INIT);
        // TX start
        enc28j60WriteWord(ETXSTL, TXSTART_INIT);
        // TX end
        enc28j60WriteWord(ETXNDL, TXSTOP_INIT);
        // do bank 1 stuff, packet filter:
        // 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

        //enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
        //Change to add ERXFCON_BCEN recommended by epam
        //enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_BCEN);
        erxfcon =  ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_BCEN;
        enc28j60Write(ERXFCON, erxfcon );
        enc28j60WriteWord(EPMM0, 0x303f);
        enc28j60WriteWord(EPMCSL, 0xf7f9);
        //
        // do bank 2 stuff
        // enable MAC receive
        enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
        // bring MAC out of reset
        enc28j60Write(MACON2, 0x00);
        // enable automatic padding to 60bytes and CRC operations
        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);  //|MACON3_FULDPX);
        // set inter-frame gap (non-back-to-back)
        enc28j60WriteWord(MAIPGL, 0x0C12);
        // set inter-frame gap (back-to-back)
        enc28j60Write(MABBIPG, 0x12);
        // Set the maximum packet size which the controller will accept
        // Do not send packets longer than MAX_FRAMELEN:
        enc28j60WriteWord(MAMXFLL, MAX_FRAMELEN);       
        // do bank 3 stuff
        // write MAC address
        // NOTE: MAC address in ENC28J60 is byte-backward
        enc28j60Write(MAADR5, macaddr[0]);
        enc28j60Write(MAADR4, macaddr[1]);
        enc28j60Write(MAADR3, macaddr[2]);
        enc28j60Write(MAADR2, macaddr[3]);
        enc28j60Write(MAADR1, macaddr[4]);
        enc28j60Write(MAADR0, macaddr[5]);
        // no loopback of transmitted frames
        enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS);
        // switch to bank 0
        enc28j60SetBank(ECON1);
        // enable interrutps
        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
        // enable packet reception
        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
       
        LCD_String(20,80,"Mac Init",GREEN);
}

// read the revision of the chip:
uint8_t enc28j60getrev(void)
{
        uint8_t rev;
        rev=enc28j60Read(EREVID);
        // microchip forgot to step the number on the silcon when they
        // released the revision B7. 6 is now rev B7. We still have
        // to see what they do when they release B8. At the moment
        // there is no B8 out yet
        if (rev>5) rev++;
        return(rev);
}

// A number of utility functions to enable/disable broadcast and multicast bits
void enc28j60EnableBroadcast( void ) {
        erxfcon |= ERXFCON_BCEN;
        enc28j60Write(ERXFCON, erxfcon);
}

void enc28j60DisableBroadcast( void ) {
        erxfcon &= (0xff ^ ERXFCON_BCEN);
        enc28j60Write(ERXFCON, erxfcon);
}

void enc28j60EnableMulticast( void ) {
        erxfcon |= ERXFCON_MCEN;
        enc28j60Write(ERXFCON, erxfcon);
}

void enc28j60DisableMulticast( void ) {
        erxfcon &= (0xff ^ ERXFCON_MCEN);
        enc28j60Write(ERXFCON, erxfcon);
}


// link status
uint8_t enc28j60linkup(void)
{
        // bit 10 (= bit 3 in upper reg)
        return(enc28j60PhyReadH(PHSTAT2) && 4);
}

void enc28j60PacketSend(uint16_t len, uint8_t* packet)
{
        // Check no transmit in progress
        while (enc28j60ReadOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_TXRTS)
        {
                // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
                if( (enc28j60Read(EIR) & EIR_TXERIF) ) {
                        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
                        enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
                }
        }

        // Set the write pointer to start of transmit buffer area
        enc28j60WriteWord(EWRPTL, TXSTART_INIT);
        // Set the TXND pointer to correspond to the packet size given
        enc28j60WriteWord(ETXNDL, (TXSTART_INIT+len));
        // write per-packet control byte (0x00 means use macon3 settings)
        enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
        // copy the packet into the transmit buffer
        enc28j60WriteBuffer(len, packet);
        // send the contents of the transmit buffer onto the network
        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
        // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
}

// just probe if there might be a packet
//uint8_t enc28j60hasRxPkt(void)
//{
//       return enc28j60ReadByte(EPKTCNT) > 0;
//}

// Gets a packet from the network receive buffer, if one is available.
// The packet will by headed by an ethernet header.
//      maxlen  The maximum acceptable length of a retrieved packet.
//      packet  Pointer where packet data should be stored.
// Returns: Packet length in bytes if a packet was retrieved, zero otherwise.
uint16_t enc28j60PacketReceive(uint16_t maxlen, uint8_t* packet)
{
                uint16_t rxstat;
        uint16_t len;
        // check if a packet has been received and buffered
        //if( !(enc28j60Read(EIR) & EIR_PKTIF) ){
        // The above does not work. See Rev. B4 Silicon Errata point 6.
        if( enc28j60Read(EPKTCNT) ==0 ){
                return(0);
        }

        // Set the read pointer to the start of the received packet
        enc28j60WriteWord(ERDPTL, gNextPacketPtr);
        //enc28j60Write(ERDPTL, (gNextPacketPtr &0xFF));
        //enc28j60Write(ERDPTH, (gNextPacketPtr)>>8);
        // read the next packet pointer
        gNextPacketPtr  = enc28j60ReadBufferWord();
        //gNextPacketPtr  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
        //gNextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;
        // read the packet length (see datasheet page 43)
        len = enc28j60ReadBufferWord() - 4;
        //len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
        //len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;
        //len-=4; //remove the CRC count
        // read the receive status (see datasheet page 43)
        rxstat  = enc28j60ReadBufferWord();
        //rxstat  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
        //rxstat |= ((uint16_t)enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0))<<8;
        // limit retrieve length
        if (len>maxlen-1){
                len=maxlen-1;
        }
        // check CRC and symbol errors (see datasheet page 44, table 7-3):
        // The ERXFCON.CRCEN is set by default. Normally we should not
        // need to check this.
        if ((rxstat & 0x80)==0){
                // invalid
                len=0;
        }else{
                // copy the packet from the receive buffer
                enc28j60ReadBuffer(len, packet);
        }
        // Move the RX read pointer to the start of the next received packet
        // This frees the memory we just read out
        enc28j60WriteWord(ERXRDPTL, gNextPacketPtr );
        //enc28j60Write(ERXRDPTL, (gNextPacketPtr &0xFF));
        //enc28j60Write(ERXRDPTH, (gNextPacketPtr)>>8);
        // However, compensate for the errata point 13, rev B4: enver write an even address!
        if ((gNextPacketPtr - 1 < RXSTART_INIT)
                || (gNextPacketPtr -1 > RXSTOP_INIT)) {
                enc28j60WriteWord(ERXRDPTL, RXSTOP_INIT);
                //enc28j60Write(ERXRDPTL, (RXSTOP_INIT)&0xFF);
                //enc28j60Write(ERXRDPTH, (RXSTOP_INIT)>>8);
        } else {
                enc28j60WriteWord(ERXRDPTL, (gNextPacketPtr-1));
                //enc28j60Write(ERXRDPTL, (gNextPacketPtr-1)&0xFF);
                //enc28j60Write(ERXRDPTH, (gNextPacketPtr-1)>>8);
        }
        // decrement the packet counter indicate we are done with this packet
        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
        return(len);

}



20131002013511953.jpg (1.15 MB, downloads: 0)

20131002013511953.jpg

20131002014151765.jpg (219.24 KB, downloads: 0)

20131002014151765.jpg
This post is from stm32/stm8
 
 

8

Posts

0

Resources
3
 
The problem has been solved, thank you, it was a problem with the spi configuration
This post is from stm32/stm8
 
 

Guess Your Favourite
Find a datasheet?

EEWorld Datasheet Technical Support

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list