#include "STM_ENC28_J60.h" //variables extern SPI_HandleTypeDef hspi1; static uint8_t Enc28_Bank; uint8_t dataWatch8; uint16_t dataWatch16; uint8_t ENC28_readOp(uint8_t oper, uint8_t addr) { uint8_t spiData[2]; HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_RESET); spiData[0] = (oper| (addr & ADDR_MASK)); HAL_SPI_Transmit(&hspi1, spiData, 1, 100); if(addr & 0x80) { //HAL_SPI_Transmit(&hspi1, spiData, 1, 100); HAL_SPI_Receive(&hspi1, &spiData[1], 1, 100); } HAL_SPI_Receive(&hspi1, &spiData[1], 1, 100); HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_SET); return spiData[1]; } void ENC28_writeOp(uint8_t oper, uint8_t addr, uint8_t data) { uint8_t spiData[2]; HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_RESET); spiData[0] = (oper| (addr & ADDR_MASK)); //((oper<<5)&0xE0)|(addr & ADDR_MASK); spiData[1] = data; HAL_SPI_Transmit(&hspi1, spiData, 2, 100); HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_SET); } uint8_t ENC28_readReg8(uint8_t addr) { ENC28_setBank(addr); return ENC28_readOp(ENC28_READ_CTRL_REG, addr); } void ENC28_writeReg8(uint8_t addr, uint8_t data) { ENC28_setBank(addr); ENC28_writeOp(ENC28_WRITE_CTRL_REG, addr, data); } uint16_t ENC28_readReg16( uint8_t addr) { return ENC28_readReg8(addr) + (ENC28_readReg8(addr+1) << 8); } void ENC28_writeReg16(uint8_t addrL, uint16_t data) { ENC28_writeReg8(addrL, data); ENC28_writeReg8(addrL+1, data >> 8); } void ENC28_setBank(uint8_t addr) { if ((addr & BANK_MASK) != Enc28_Bank) { ENC28_writeOp(ENC28_BIT_FIELD_CLR, ECON1, ECON1_BSEL1|ECON1_BSEL0); Enc28_Bank = addr & BANK_MASK; ENC28_writeOp(ENC28_BIT_FIELD_SET, ECON1, Enc28_Bank>>5); } } void ENC28_writePhy(uint8_t addr, uint16_t data) { ENC28_writeReg8(MIREGADR, addr); ENC28_writeReg8(MIWR, data); while (ENC28_readReg8(MISTAT) & MISTAT_BUSY); } uint16_t ENC28_readPhy(uint8_t addr) { ENC28_writeReg8(MIREGADR, addr); // pass the PHY address to the MII ENC28_writeReg8(MICMD, MICMD_MIIRD); // Enable Read bit while (ENC28_readReg8(MISTAT) & MISTAT_BUSY); // Poll for end of reading ENC28_writeReg8(MICMD, 0x00); // Disable MII Read return ENC28_readReg8(MIRD) + (ENC28_readReg8(MIRD+1) << 8); } void ENC28_Init(void) { uint8_t spiData[2]; // (1): Disable the chip CS pin HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_SET); HAL_Delay(1); // (2): Perform soft reset to the ENC28J60 module ENC28_writeOp(ENC28_SOFT_RESET, 0, ENC28_SOFT_RESET); HAL_Delay(2); // (3): Wait untill Clock is ready while(!ENC28_readOp(ENC28_READ_CTRL_REG, ESTAT) & ESTAT_CLKRDY); // (4): Initialise RX and TX buffer size ENC28_writeReg16(ERXST, RXSTART_INIT); ENC28_writeReg16(ERXND, RXSTOP_INIT); ENC28_writeReg16(ETXST, TXSTART_INIT); ENC28_writeReg16(ETXND, TXSTOP_INIT); ENC28_writeReg16(ERXRDPT, RXSTART_INIT); ENC28_writeReg16(ERXWRPT, RXSTART_INIT); dataWatch16 = ENC28_readReg16(ERXND); // (5): Reviece buffer filters ENC28_writeReg8(ERXFCON, ERXFCON_UCEN|ERXFCON_ANDOR|ERXFCON_CRCEN); dataWatch8 = ENC28_readReg8(ERXFCON); // (6): MAC Control Register 1 ENC28_writeReg8(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS|MACON1_PASSALL); dataWatch8 = ENC28_readReg8(ERXFCON); // (7): MAC Control Register 3 ENC28_writeOp(ENC28_BIT_FIELD_SET, MACON3,MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); // (8): NON/Back to back gap ENC28_writeReg16(MAIPG, 0x0C12); // NonBackToBack gap ENC28_writeReg8(MABBIPG, 0x12); // BackToBack gap // (9): Set Maximum framelenght ENC28_writeReg16(MAMXFL, MAX_FRAMELEN); // Set Maximum frame length (any packet bigger will be discarded) // (10): Set the MAC address of the device ENC28_writeReg8(MAADR1, MAC_1); ENC28_writeReg8(MAADR2, MAC_2); ENC28_writeReg8(MAADR3, MAC_3); ENC28_writeReg8(MAADR4, MAC_4); ENC28_writeReg8(MAADR5, MAC_5); ENC28_writeReg8(MAADR6, MAC_6); dataWatch8 = ENC28_readReg8(MAADR1); dataWatch8 = ENC28_readReg8(MAADR2); dataWatch8 = ENC28_readReg8(MAADR3); dataWatch8 = ENC28_readReg8(MAADR4); dataWatch8 = ENC28_readReg8(MAADR5); dataWatch8 = ENC28_readReg8(MAADR6); if(dataWatch8==MAC_6)HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET); //**********Advanced Initialisations************// // (1): Initialise PHY layer registers ENC28_writePhy(PHLCON, PHLCON_LED); ENC28_writePhy(PHCON2, PHCON2_HDLDIS); // (2): Enable Rx interrupt line ENC28_setBank(ECON1); ENC28_writeOp(ENC28_BIT_FIELD_SET, ECON1, ECON1_RXEN); // ENC28_writeOp(ENC28_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); // ENC28_writeOp(ENC28_BIT_FIELD_SET, EIR, EIR_PKTIF); } void ENC28_packetSend(uint16_t len, uint8_t* dataBuf) { uint8_t retry = 0; while(1) { ENC28_writeOp(ENC28_BIT_FIELD_SET, ECON1, ECON1_TXRST); ENC28_writeOp(ENC28_BIT_FIELD_CLR, ECON1, ECON1_TXRST); ENC28_writeOp(ENC28_BIT_FIELD_CLR, EIR, EIR_TXERIF|EIR_TXIF); // prepare new transmission if(retry == 0) { ENC28_writeReg16(EWRPT, TXSTART_INIT); ENC28_writeReg16(ETXND, TXSTART_INIT+len); ENC28_writeOp(ENC28_WRITE_BUF_MEM, 0, 0); //line 485 enc28j60.cpp ENC28_writeBuf(len, dataBuf); } // initiate transmission ENC28_writeOp(ENC28_BIT_FIELD_SET, ECON1, ECON1_TXRTS); uint16_t count = 0; while ((ENC28_readReg8(EIR) & (EIR_TXIF | EIR_TXERIF)) == 0 && ++count < 1000U); if (!(ENC28_readReg8(EIR) & EIR_TXERIF) && count < 1000U) { // no error; start new transmission break; } // cancel previous transmission if stuck ENC28_writeOp(ENC28_BIT_FIELD_CLR, ECON1, ECON1_TXRTS); break; } } void ENC28_writeBuf(uint16_t len, uint8_t* data) { uint8_t spiData[2]; HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_RESET); spiData[0] = ENC28_WRITE_BUF_MEM; HAL_SPI_Transmit(&hspi1, spiData, 1, 100); HAL_SPI_Transmit(&hspi1, data, len, 100); HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_SET); }