123

Committer:
hudakz
Date:
Fri Aug 30 08:11:40 2019 +0000
Revision:
11:647d53d146f1
Parent:
utility/Enc28j60Py.cpp@9:a156d3de5647
Child:
14:7648334eb41b
"set_network" method of Mbed style added.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 9:a156d3de5647 1 /*
hudakz 9:a156d3de5647 2 Enc28J60Network.cpp
hudakz 9:a156d3de5647 3 UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface.
hudakz 9:a156d3de5647 4
hudakz 9:a156d3de5647 5 Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
hudakz 9:a156d3de5647 6 All rights reserved.
hudakz 9:a156d3de5647 7
hudakz 9:a156d3de5647 8 based on enc28j60.c file from the AVRlib library by Pascal Stang.
hudakz 9:a156d3de5647 9 For AVRlib See http://www.procyonengineering.com/
hudakz 9:a156d3de5647 10
hudakz 9:a156d3de5647 11 Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.com>
hudakz 9:a156d3de5647 12
hudakz 9:a156d3de5647 13 This program is free software: you can redistribute it and/or modify
hudakz 9:a156d3de5647 14 it under the terms of the GNU General Public License as published by
hudakz 9:a156d3de5647 15 the Free Software Foundation, either version 3 of the License, or
hudakz 9:a156d3de5647 16 (at your option) any later version.
hudakz 9:a156d3de5647 17
hudakz 9:a156d3de5647 18 This program is distributed in the hope that it will be useful,
hudakz 9:a156d3de5647 19 but WITHOUT ANY WARRANTY; without even the implied warranty of
hudakz 9:a156d3de5647 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
hudakz 9:a156d3de5647 21 GNU General Public License for more details.
hudakz 9:a156d3de5647 22
hudakz 9:a156d3de5647 23 You should have received a copy of the GNU General Public License
hudakz 9:a156d3de5647 24 along with this program. If not, see <http://www.gnu.org/licenses/>.
hudakz 9:a156d3de5647 25 */
hudakz 11:647d53d146f1 26 #include "Enc28j60Eth.h"
hudakz 9:a156d3de5647 27 #include "mbed.h"
hudakz 9:a156d3de5647 28
hudakz 9:a156d3de5647 29 extern "C"
hudakz 9:a156d3de5647 30 {
hudakz 9:a156d3de5647 31 #include "enc28j60.h"
hudakz 9:a156d3de5647 32 #include "uip.h"
hudakz 9:a156d3de5647 33 }
hudakz 9:a156d3de5647 34
hudakz 9:a156d3de5647 35 // Static member initialization
hudakz 11:647d53d146f1 36 uint16_t Enc28j60Eth::nextPacketPtr;
hudakz 11:647d53d146f1 37 uint8_t Enc28j60Eth::bank = 0xff;
hudakz 11:647d53d146f1 38 struct memblock Enc28j60Eth::receivePkt;
hudakz 9:a156d3de5647 39
hudakz 9:a156d3de5647 40 /**
hudakz 9:a156d3de5647 41 * @brief
hudakz 9:a156d3de5647 42 * @note
hudakz 9:a156d3de5647 43 * @param
hudakz 9:a156d3de5647 44 * @retval
hudakz 9:a156d3de5647 45 */
hudakz 11:647d53d146f1 46 Enc28j60Eth::Enc28j60Eth(PinName mosi, PinName miso, PinName sclk, PinName cs) :
hudakz 9:a156d3de5647 47 MemPool(),
hudakz 9:a156d3de5647 48 _spi(mosi, miso, sclk),
hudakz 9:a156d3de5647 49 _cs(cs)
hudakz 9:a156d3de5647 50 { }
hudakz 9:a156d3de5647 51
hudakz 9:a156d3de5647 52 /**
hudakz 9:a156d3de5647 53 * @brief
hudakz 9:a156d3de5647 54 * @note
hudakz 9:a156d3de5647 55 * @param
hudakz 9:a156d3de5647 56 * @retval
hudakz 9:a156d3de5647 57 */
hudakz 11:647d53d146f1 58 void Enc28j60Eth::init(uint8_t* macaddr)
hudakz 9:a156d3de5647 59 {
hudakz 9:a156d3de5647 60 MemPool::init(); // 1 byte in between RX_STOP_INIT and pool to allow prepending of controlbyte
hudakz 9:a156d3de5647 61 // initialize SPI interface
hudakz 9:a156d3de5647 62 _spi.format(8, 0); // 8-bit, mode 0
hudakz 11:647d53d146f1 63 _spi.frequency(20000000); // 20 Mbit/s
hudakz 9:a156d3de5647 64 wait_ms(1000); // 1 second for stable state
hudakz 9:a156d3de5647 65 // Release SPI
hudakz 9:a156d3de5647 66 _cs = 1;
hudakz 9:a156d3de5647 67
hudakz 9:a156d3de5647 68 // perform system reset
hudakz 9:a156d3de5647 69 writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
hudakz 9:a156d3de5647 70
hudakz 9:a156d3de5647 71 // check CLKRDY bit to see if reset is complete
hudakz 9:a156d3de5647 72 //while(!(readReg(ESTAT) & ESTAT_CLKRDY));
hudakz 9:a156d3de5647 73 // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
hudakz 9:a156d3de5647 74 wait_ms(50);
hudakz 9:a156d3de5647 75
hudakz 9:a156d3de5647 76 // do bank 0 stuff
hudakz 9:a156d3de5647 77 // initialize receive buffer
hudakz 9:a156d3de5647 78 // 16-bit transfers, must write low byte first
hudakz 9:a156d3de5647 79 // set receive buffer start address
hudakz 9:a156d3de5647 80 nextPacketPtr = RXSTART_INIT;
hudakz 9:a156d3de5647 81
hudakz 9:a156d3de5647 82 // Rx start
hudakz 9:a156d3de5647 83 writeRegPair(ERXSTL, RXSTART_INIT);
hudakz 9:a156d3de5647 84
hudakz 9:a156d3de5647 85 // set receive pointer address
hudakz 9:a156d3de5647 86 writeRegPair(ERXRDPTL, RXSTART_INIT);
hudakz 9:a156d3de5647 87
hudakz 9:a156d3de5647 88 // RX end
hudakz 11:647d53d146f1 89 writeRegPair(ERXNDL, RXEND_INIT);
hudakz 9:a156d3de5647 90
hudakz 11:647d53d146f1 91 //All memory which is not used by the receive buffer is considered the transmission buffer.
hudakz 11:647d53d146f1 92 // No explicit action is required to initialize the transmission buffer.
hudakz 11:647d53d146f1 93 // However, he host controller should leave at least seven bytes between each
hudakz 11:647d53d146f1 94 // packet and the beginning of the receive buffer.
hudakz 9:a156d3de5647 95 // TX start
hudakz 9:a156d3de5647 96 //writeRegPair(ETXSTL, TXSTART_INIT);
hudakz 9:a156d3de5647 97 // TX end
hudakz 11:647d53d146f1 98 //writeRegPair(ETXNDL, TXEND_INIT);
hudakz 11:647d53d146f1 99
hudakz 9:a156d3de5647 100 // do bank 1 stuff, packet filter:
hudakz 9:a156d3de5647 101 // For broadcast packets we allow only ARP packtets
hudakz 9:a156d3de5647 102 // All other packets should be unicast only for our mac (MAADR)
hudakz 9:a156d3de5647 103 //
hudakz 9:a156d3de5647 104 // The pattern to match on is therefore
hudakz 9:a156d3de5647 105 // Type ETH.DST
hudakz 9:a156d3de5647 106 // ARP BROADCAST
hudakz 9:a156d3de5647 107 // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
hudakz 9:a156d3de5647 108 // in binary these poitions are:11 0000 0011 1111
hudakz 9:a156d3de5647 109 // This is hex 303F->EPMM0=0x3f,EPMM1=0x30
hudakz 9:a156d3de5647 110 //TODO define specific pattern to receive dhcp-broadcast packages instead of setting ERFCON_BCEN!
hudakz 9:a156d3de5647 111 writeReg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_PMEN | ERXFCON_BCEN);
hudakz 9:a156d3de5647 112 writeRegPair(EPMM0, 0x303f);
hudakz 9:a156d3de5647 113 writeRegPair(EPMCSL, 0xf7f9);
hudakz 9:a156d3de5647 114
hudakz 9:a156d3de5647 115 //
hudakz 9:a156d3de5647 116 //
hudakz 11:647d53d146f1 117 // do bank 2 stuff,
hudakz 9:a156d3de5647 118 // enable MAC receive
hudakz 9:a156d3de5647 119 // and bring MAC out of reset (writes 0x00 to MACON2)
hudakz 9:a156d3de5647 120 writeRegPair(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
hudakz 9:a156d3de5647 121
hudakz 9:a156d3de5647 122 // enable automatic padding to 60bytes and CRC operations
hudakz 9:a156d3de5647 123 writeOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN);
hudakz 9:a156d3de5647 124
hudakz 9:a156d3de5647 125 // set inter-frame gap (non-back-to-back)
hudakz 9:a156d3de5647 126 writeRegPair(MAIPGL, 0x0C12);
hudakz 9:a156d3de5647 127
hudakz 9:a156d3de5647 128 // set inter-frame gap (back-to-back)
hudakz 9:a156d3de5647 129 writeReg(MABBIPG, 0x12);
hudakz 9:a156d3de5647 130
hudakz 9:a156d3de5647 131 // Set the maximum packet size which the controller will accept
hudakz 9:a156d3de5647 132 // Do not send packets longer than MAX_FRAMELEN:
hudakz 9:a156d3de5647 133 writeRegPair(MAMXFLL, MAX_FRAMELEN);
hudakz 9:a156d3de5647 134
hudakz 9:a156d3de5647 135 // do bank 3 stuff
hudakz 9:a156d3de5647 136 // write MAC address
hudakz 9:a156d3de5647 137 // NOTE: MAC address in ENC28J60 is byte-backward
hudakz 9:a156d3de5647 138 writeReg(MAADR5, macaddr[0]);
hudakz 9:a156d3de5647 139 writeReg(MAADR4, macaddr[1]);
hudakz 9:a156d3de5647 140 writeReg(MAADR3, macaddr[2]);
hudakz 9:a156d3de5647 141 writeReg(MAADR2, macaddr[3]);
hudakz 9:a156d3de5647 142 writeReg(MAADR1, macaddr[4]);
hudakz 9:a156d3de5647 143 writeReg(MAADR0, macaddr[5]);
hudakz 9:a156d3de5647 144
hudakz 9:a156d3de5647 145 // no loopback of transmitted frames
hudakz 9:a156d3de5647 146 phyWrite(PHCON2, PHCON2_HDLDIS);
hudakz 9:a156d3de5647 147
hudakz 9:a156d3de5647 148 // switch to bank 0
hudakz 9:a156d3de5647 149 setBank(ECON1);
hudakz 9:a156d3de5647 150
hudakz 9:a156d3de5647 151 // enable interrutps
hudakz 9:a156d3de5647 152 writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE | EIE_PKTIE);
hudakz 9:a156d3de5647 153
hudakz 9:a156d3de5647 154 // enable packet reception
hudakz 9:a156d3de5647 155 writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
hudakz 9:a156d3de5647 156
hudakz 9:a156d3de5647 157 //Configure leds
hudakz 9:a156d3de5647 158 phyWrite(PHLCON, 0x476);
hudakz 9:a156d3de5647 159 }
hudakz 9:a156d3de5647 160
hudakz 9:a156d3de5647 161 /**
hudakz 9:a156d3de5647 162 * @brief
hudakz 9:a156d3de5647 163 * @note
hudakz 9:a156d3de5647 164 * @param
hudakz 9:a156d3de5647 165 * @retval
hudakz 9:a156d3de5647 166 */
hudakz 11:647d53d146f1 167 memhandle Enc28j60Eth::receivePacket()
hudakz 9:a156d3de5647 168 {
hudakz 9:a156d3de5647 169 uint8_t rxstat;
hudakz 9:a156d3de5647 170 uint16_t len;
hudakz 9:a156d3de5647 171 // check if a packet has been received and buffered
hudakz 9:a156d3de5647 172 //if( !(readReg(EIR) & EIR_PKTIF) ){
hudakz 9:a156d3de5647 173 // The above does not work. See Rev. B4 Silicon Errata point 6.
hudakz 9:a156d3de5647 174 if (readReg(EPKTCNT) != 0) {
hudakz 9:a156d3de5647 175 uint16_t readPtr = nextPacketPtr +
hudakz 11:647d53d146f1 176 6 > RXEND_INIT ? nextPacketPtr +
hudakz 9:a156d3de5647 177 6 -
hudakz 11:647d53d146f1 178 RXEND_INIT +
hudakz 9:a156d3de5647 179 RXSTART_INIT : nextPacketPtr +
hudakz 9:a156d3de5647 180 6;
hudakz 9:a156d3de5647 181 // Set the read pointer to the start of the received packet
hudakz 9:a156d3de5647 182 writeRegPair(ERDPTL, nextPacketPtr);
hudakz 9:a156d3de5647 183
hudakz 9:a156d3de5647 184 // read the next packet pointer
hudakz 9:a156d3de5647 185 nextPacketPtr = readOp(ENC28J60_READ_BUF_MEM, 0);
hudakz 9:a156d3de5647 186 nextPacketPtr |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
hudakz 9:a156d3de5647 187
hudakz 9:a156d3de5647 188 // read the packet length (see datasheet page 43)
hudakz 9:a156d3de5647 189 len = readOp(ENC28J60_READ_BUF_MEM, 0);
hudakz 9:a156d3de5647 190 len |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
hudakz 9:a156d3de5647 191 len -= 4; //remove the CRC count
hudakz 9:a156d3de5647 192 // read the receive status (see datasheet page 43)
hudakz 9:a156d3de5647 193 rxstat = readOp(ENC28J60_READ_BUF_MEM, 0);
hudakz 9:a156d3de5647 194
hudakz 9:a156d3de5647 195 //rxstat |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
hudakz 9:a156d3de5647 196 #ifdef ENC28J60DEBUG
hudakz 9:a156d3de5647 197 printf
hudakz 9:a156d3de5647 198 (
hudakz 9:a156d3de5647 199 "receivePacket [%d-%d], next: %d, stat: %d, count: %d -> ",
hudakz 9:a156d3de5647 200 readPtr,
hudakz 11:647d53d146f1 201 (readPtr + len) % (RXEND_INIT + 1),
hudakz 9:a156d3de5647 202 nextPacketPtr,
hudakz 9:a156d3de5647 203 rxstat,
hudakz 9:a156d3de5647 204 readReg(EPKTCNT)
hudakz 9:a156d3de5647 205 );
hudakz 9:a156d3de5647 206 (rxstat & 0x80) != 0 ? printf("OK") : printf("failed");
hudakz 9:a156d3de5647 207 printf("\r\n");
hudakz 9:a156d3de5647 208 #endif
hudakz 9:a156d3de5647 209 // decrement the packet counter indicate we are done with this packet
hudakz 9:a156d3de5647 210
hudakz 9:a156d3de5647 211 writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
hudakz 9:a156d3de5647 212
hudakz 9:a156d3de5647 213 // check CRC and symbol errors (see datasheet page 44, table 7-3):
hudakz 9:a156d3de5647 214 // The ERXFCON.CRCEN is set by default. Normally we should not
hudakz 9:a156d3de5647 215 // need to check this.
hudakz 9:a156d3de5647 216 if ((rxstat & 0x80) != 0) {
hudakz 9:a156d3de5647 217 receivePkt.begin = readPtr;
hudakz 9:a156d3de5647 218 receivePkt.size = len;
hudakz 9:a156d3de5647 219 return UIP_RECEIVEBUFFERHANDLE;
hudakz 9:a156d3de5647 220 }
hudakz 9:a156d3de5647 221
hudakz 9:a156d3de5647 222 // Move the RX read pointer to the start of the next received packet
hudakz 9:a156d3de5647 223 // This frees the memory we just read out
hudakz 9:a156d3de5647 224 setERXRDPT();
hudakz 9:a156d3de5647 225 }
hudakz 9:a156d3de5647 226
hudakz 9:a156d3de5647 227 return(NOBLOCK);
hudakz 9:a156d3de5647 228 }
hudakz 9:a156d3de5647 229
hudakz 9:a156d3de5647 230 /**
hudakz 9:a156d3de5647 231 * @brief
hudakz 9:a156d3de5647 232 * @note
hudakz 9:a156d3de5647 233 * @param
hudakz 9:a156d3de5647 234 * @retval
hudakz 9:a156d3de5647 235 */
hudakz 11:647d53d146f1 236 void Enc28j60Eth::setERXRDPT()
hudakz 9:a156d3de5647 237 {
hudakz 11:647d53d146f1 238 writeRegPair(ERXRDPTL, nextPacketPtr == RXSTART_INIT ? RXEND_INIT : nextPacketPtr - 1);
hudakz 9:a156d3de5647 239 }
hudakz 9:a156d3de5647 240
hudakz 9:a156d3de5647 241 /**
hudakz 9:a156d3de5647 242 * @brief
hudakz 9:a156d3de5647 243 * @note
hudakz 9:a156d3de5647 244 * @param
hudakz 9:a156d3de5647 245 * @retval
hudakz 9:a156d3de5647 246 */
hudakz 11:647d53d146f1 247 memaddress Enc28j60Eth::blockSize(memhandle handle)
hudakz 9:a156d3de5647 248 {
hudakz 9:a156d3de5647 249 return handle == NOBLOCK ? 0 : handle == UIP_RECEIVEBUFFERHANDLE ? receivePkt.size : blocks[handle].size;
hudakz 9:a156d3de5647 250 }
hudakz 9:a156d3de5647 251
hudakz 9:a156d3de5647 252 /**
hudakz 9:a156d3de5647 253 * @brief
hudakz 9:a156d3de5647 254 * @note
hudakz 9:a156d3de5647 255 * @param
hudakz 9:a156d3de5647 256 * @retval
hudakz 9:a156d3de5647 257 */
hudakz 11:647d53d146f1 258 void Enc28j60Eth::sendPacket(memhandle handle)
hudakz 9:a156d3de5647 259 {
hudakz 9:a156d3de5647 260 memblock* packet = &blocks[handle];
hudakz 9:a156d3de5647 261 uint16_t start = packet->begin - 1;
hudakz 9:a156d3de5647 262 uint16_t end = start + packet->size;
hudakz 9:a156d3de5647 263
hudakz 9:a156d3de5647 264 // backup data at control-byte position
hudakz 9:a156d3de5647 265 uint8_t data = readByte(start);
hudakz 9:a156d3de5647 266 // write control-byte (if not 0 anyway)
hudakz 9:a156d3de5647 267 if (data)
hudakz 9:a156d3de5647 268 writeByte(start, 0);
hudakz 9:a156d3de5647 269
hudakz 9:a156d3de5647 270 #ifdef ENC28J60DEBUG
hudakz 9:a156d3de5647 271 printf("sendPacket(%d) [%d-%d]: ", handle, start, end);
hudakz 9:a156d3de5647 272 for (uint16_t i = start; i <= end; i++) {
hudakz 9:a156d3de5647 273 printf("%d ", readByte(i));
hudakz 9:a156d3de5647 274 }
hudakz 9:a156d3de5647 275
hudakz 9:a156d3de5647 276 printf("\r\n");
hudakz 9:a156d3de5647 277 #endif
hudakz 9:a156d3de5647 278 // TX start
hudakz 9:a156d3de5647 279
hudakz 9:a156d3de5647 280 writeRegPair(ETXSTL, start);
hudakz 9:a156d3de5647 281
hudakz 9:a156d3de5647 282 // Set the TXND pointer to correspond to the packet size given
hudakz 9:a156d3de5647 283 writeRegPair(ETXNDL, end);
hudakz 9:a156d3de5647 284
hudakz 9:a156d3de5647 285 // send the contents of the transmit buffer onto the network
hudakz 9:a156d3de5647 286 writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
hudakz 9:a156d3de5647 287
hudakz 9:a156d3de5647 288 // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
hudakz 9:a156d3de5647 289 if ((readReg(EIR) & EIR_TXERIF)) {
hudakz 9:a156d3de5647 290 writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
hudakz 9:a156d3de5647 291 }
hudakz 9:a156d3de5647 292
hudakz 9:a156d3de5647 293 //restore data on control-byte position
hudakz 9:a156d3de5647 294 if (data)
hudakz 9:a156d3de5647 295 writeByte(start, data);
hudakz 9:a156d3de5647 296 }
hudakz 9:a156d3de5647 297
hudakz 9:a156d3de5647 298 /**
hudakz 9:a156d3de5647 299 * @brief
hudakz 9:a156d3de5647 300 * @note
hudakz 9:a156d3de5647 301 * @param
hudakz 9:a156d3de5647 302 * @retval
hudakz 9:a156d3de5647 303 */
hudakz 11:647d53d146f1 304 uint16_t Enc28j60Eth::setReadPtr(memhandle handle, memaddress position, uint16_t len)
hudakz 9:a156d3de5647 305 {
hudakz 9:a156d3de5647 306 memblock* packet = handle == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[handle];
hudakz 9:a156d3de5647 307 memaddress start = handle == UIP_RECEIVEBUFFERHANDLE &&
hudakz 9:a156d3de5647 308 packet->begin +
hudakz 11:647d53d146f1 309 position > RXEND_INIT ? packet->begin +
hudakz 9:a156d3de5647 310 position -
hudakz 11:647d53d146f1 311 RXEND_INIT +
hudakz 9:a156d3de5647 312 RXSTART_INIT : packet->begin +
hudakz 9:a156d3de5647 313 position;
hudakz 9:a156d3de5647 314
hudakz 9:a156d3de5647 315 writeRegPair(ERDPTL, start);
hudakz 9:a156d3de5647 316
hudakz 9:a156d3de5647 317 if (len > packet->size - position)
hudakz 9:a156d3de5647 318 len = packet->size - position;
hudakz 9:a156d3de5647 319 return len;
hudakz 9:a156d3de5647 320 }
hudakz 9:a156d3de5647 321
hudakz 9:a156d3de5647 322 /**
hudakz 9:a156d3de5647 323 * @brief
hudakz 9:a156d3de5647 324 * @note
hudakz 9:a156d3de5647 325 * @param
hudakz 9:a156d3de5647 326 * @retval
hudakz 9:a156d3de5647 327 */
hudakz 11:647d53d146f1 328 uint16_t Enc28j60Eth::readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len)
hudakz 9:a156d3de5647 329 {
hudakz 9:a156d3de5647 330 len = setReadPtr(handle, position, len);
hudakz 9:a156d3de5647 331 readBuffer(len, buffer);
hudakz 9:a156d3de5647 332 return len;
hudakz 9:a156d3de5647 333 }
hudakz 9:a156d3de5647 334
hudakz 9:a156d3de5647 335 /**
hudakz 9:a156d3de5647 336 * @brief
hudakz 9:a156d3de5647 337 * @note
hudakz 9:a156d3de5647 338 * @param
hudakz 9:a156d3de5647 339 * @retval
hudakz 9:a156d3de5647 340 */
hudakz 11:647d53d146f1 341 uint16_t Enc28j60Eth::writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len)
hudakz 9:a156d3de5647 342 {
hudakz 9:a156d3de5647 343 memblock* packet = &blocks[handle];
hudakz 9:a156d3de5647 344 uint16_t start = packet->begin + position;
hudakz 9:a156d3de5647 345
hudakz 9:a156d3de5647 346 writeRegPair(EWRPTL, start);
hudakz 9:a156d3de5647 347
hudakz 9:a156d3de5647 348 if (len > packet->size - position)
hudakz 9:a156d3de5647 349 len = packet->size - position;
hudakz 9:a156d3de5647 350 writeBuffer(len, buffer);
hudakz 9:a156d3de5647 351 return len;
hudakz 9:a156d3de5647 352 }
hudakz 9:a156d3de5647 353
hudakz 9:a156d3de5647 354 /**
hudakz 9:a156d3de5647 355 * @brief
hudakz 9:a156d3de5647 356 * @note
hudakz 9:a156d3de5647 357 * @param
hudakz 9:a156d3de5647 358 * @retval
hudakz 9:a156d3de5647 359 */
hudakz 11:647d53d146f1 360 uint8_t Enc28j60Eth::readByte(uint16_t addr)
hudakz 9:a156d3de5647 361 {
hudakz 9:a156d3de5647 362 uint8_t result;
hudakz 9:a156d3de5647 363
hudakz 9:a156d3de5647 364 writeRegPair(ERDPTL, addr);
hudakz 9:a156d3de5647 365
hudakz 9:a156d3de5647 366 _cs = 0;
hudakz 9:a156d3de5647 367
hudakz 9:a156d3de5647 368 // issue read command
hudakz 9:a156d3de5647 369 _spi.write(ENC28J60_READ_BUF_MEM);
hudakz 9:a156d3de5647 370
hudakz 9:a156d3de5647 371 // read data
hudakz 9:a156d3de5647 372 result = _spi.write(0x00);
hudakz 9:a156d3de5647 373 _cs = 1;
hudakz 9:a156d3de5647 374 return(result);
hudakz 9:a156d3de5647 375 }
hudakz 9:a156d3de5647 376
hudakz 9:a156d3de5647 377 /**
hudakz 9:a156d3de5647 378 * @brief
hudakz 9:a156d3de5647 379 * @note
hudakz 9:a156d3de5647 380 * @param
hudakz 9:a156d3de5647 381 * @retval
hudakz 9:a156d3de5647 382 */
hudakz 11:647d53d146f1 383 void Enc28j60Eth::writeByte(uint16_t addr, uint8_t data)
hudakz 9:a156d3de5647 384 {
hudakz 9:a156d3de5647 385 writeRegPair(EWRPTL, addr);
hudakz 9:a156d3de5647 386
hudakz 9:a156d3de5647 387 _cs = 0;
hudakz 9:a156d3de5647 388
hudakz 9:a156d3de5647 389 // issue write command
hudakz 9:a156d3de5647 390 _spi.write(ENC28J60_WRITE_BUF_MEM);
hudakz 9:a156d3de5647 391
hudakz 9:a156d3de5647 392 // write data
hudakz 9:a156d3de5647 393 _spi.write(data);
hudakz 9:a156d3de5647 394 _cs = 1;
hudakz 9:a156d3de5647 395 }
hudakz 9:a156d3de5647 396
hudakz 9:a156d3de5647 397 /**
hudakz 9:a156d3de5647 398 * @brief
hudakz 9:a156d3de5647 399 * @note
hudakz 9:a156d3de5647 400 * @param
hudakz 9:a156d3de5647 401 * @retval
hudakz 9:a156d3de5647 402 */
hudakz 11:647d53d146f1 403 void Enc28j60Eth::copyPacket
hudakz 9:a156d3de5647 404 (
hudakz 9:a156d3de5647 405 memhandle dest_pkt,
hudakz 9:a156d3de5647 406 memaddress dest_pos,
hudakz 9:a156d3de5647 407 memhandle src_pkt,
hudakz 9:a156d3de5647 408 memaddress src_pos,
hudakz 9:a156d3de5647 409 uint16_t len
hudakz 9:a156d3de5647 410 )
hudakz 9:a156d3de5647 411 {
hudakz 9:a156d3de5647 412 memblock* dest = &blocks[dest_pkt];
hudakz 9:a156d3de5647 413 memblock* src = src_pkt == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[src_pkt];
hudakz 9:a156d3de5647 414 memaddress start = src_pkt == UIP_RECEIVEBUFFERHANDLE &&
hudakz 9:a156d3de5647 415 src->begin +
hudakz 11:647d53d146f1 416 src_pos > RXEND_INIT ? src->begin +
hudakz 9:a156d3de5647 417 src_pos -
hudakz 11:647d53d146f1 418 RXEND_INIT +
hudakz 9:a156d3de5647 419 RXSTART_INIT : src->begin +
hudakz 9:a156d3de5647 420 src_pos;
hudakz 9:a156d3de5647 421 enc28j60_mempool_block_move_callback(dest->begin + dest_pos, start, len);
hudakz 9:a156d3de5647 422
hudakz 9:a156d3de5647 423 // Move the RX read pointer to the start of the next received packet
hudakz 9:a156d3de5647 424 // This frees the memory we just read out
hudakz 11:647d53d146f1 425 //setERXRDPT();
hudakz 9:a156d3de5647 426 }
hudakz 9:a156d3de5647 427
hudakz 9:a156d3de5647 428 /**
hudakz 9:a156d3de5647 429 * @brief
hudakz 9:a156d3de5647 430 * @note
hudakz 9:a156d3de5647 431 * @param
hudakz 9:a156d3de5647 432 * @retval
hudakz 9:a156d3de5647 433 */
hudakz 11:647d53d146f1 434 void Enc28j60Eth::freePacket()
hudakz 9:a156d3de5647 435 {
hudakz 9:a156d3de5647 436 setERXRDPT();
hudakz 9:a156d3de5647 437 }
hudakz 9:a156d3de5647 438
hudakz 9:a156d3de5647 439 /**
hudakz 9:a156d3de5647 440 * @brief
hudakz 9:a156d3de5647 441 * @note
hudakz 9:a156d3de5647 442 * @param
hudakz 9:a156d3de5647 443 * @retval
hudakz 9:a156d3de5647 444 */
hudakz 11:647d53d146f1 445 uint8_t Enc28j60Eth::readOp(uint8_t op, uint8_t address)
hudakz 9:a156d3de5647 446 {
hudakz 9:a156d3de5647 447 uint8_t result;
hudakz 9:a156d3de5647 448
hudakz 9:a156d3de5647 449 _cs = 0;
hudakz 9:a156d3de5647 450
hudakz 9:a156d3de5647 451 // issue read command
hudakz 9:a156d3de5647 452 _spi.write(op | (address & ADDR_MASK));
hudakz 9:a156d3de5647 453
hudakz 9:a156d3de5647 454 // read data
hudakz 9:a156d3de5647 455 result = _spi.write(0x00);
hudakz 9:a156d3de5647 456
hudakz 9:a156d3de5647 457 // do dummy read if needed (for mac and mii, see datasheet page 29)
hudakz 9:a156d3de5647 458 if (address & 0x80)
hudakz 9:a156d3de5647 459 result = _spi.write(0x00);
hudakz 9:a156d3de5647 460
hudakz 9:a156d3de5647 461 // release CS
hudakz 9:a156d3de5647 462 _cs = 1;
hudakz 9:a156d3de5647 463 return(result);
hudakz 9:a156d3de5647 464 }
hudakz 9:a156d3de5647 465
hudakz 9:a156d3de5647 466 /**
hudakz 9:a156d3de5647 467 * @brief
hudakz 9:a156d3de5647 468 * @note
hudakz 9:a156d3de5647 469 * @param
hudakz 9:a156d3de5647 470 * @retval
hudakz 9:a156d3de5647 471 */
hudakz 11:647d53d146f1 472 void Enc28j60Eth::writeOp(uint8_t op, uint8_t address, uint8_t data)
hudakz 9:a156d3de5647 473 {
hudakz 9:a156d3de5647 474 _cs = 0;
hudakz 9:a156d3de5647 475
hudakz 9:a156d3de5647 476 // issue write command
hudakz 9:a156d3de5647 477 _spi.write(op | (address & ADDR_MASK));
hudakz 9:a156d3de5647 478
hudakz 9:a156d3de5647 479 // write data
hudakz 9:a156d3de5647 480 _spi.write(data);
hudakz 9:a156d3de5647 481 _cs = 1;
hudakz 9:a156d3de5647 482 }
hudakz 9:a156d3de5647 483
hudakz 9:a156d3de5647 484 /**
hudakz 9:a156d3de5647 485 * @brief
hudakz 9:a156d3de5647 486 * @note
hudakz 9:a156d3de5647 487 * @param
hudakz 9:a156d3de5647 488 * @retval
hudakz 9:a156d3de5647 489 */
hudakz 11:647d53d146f1 490 void Enc28j60Eth::readBuffer(uint16_t len, uint8_t* data)
hudakz 9:a156d3de5647 491 {
hudakz 9:a156d3de5647 492 _cs = 0;
hudakz 9:a156d3de5647 493
hudakz 9:a156d3de5647 494 // issue read command
hudakz 9:a156d3de5647 495 _spi.write(ENC28J60_READ_BUF_MEM);
hudakz 9:a156d3de5647 496 while (len) {
hudakz 9:a156d3de5647 497 len--;
hudakz 9:a156d3de5647 498
hudakz 9:a156d3de5647 499 // read data
hudakz 9:a156d3de5647 500 *data = _spi.write(0x00);
hudakz 9:a156d3de5647 501 data++;
hudakz 9:a156d3de5647 502 }
hudakz 9:a156d3de5647 503
hudakz 9:a156d3de5647 504 *data = '\0';
hudakz 9:a156d3de5647 505 _cs = 1;
hudakz 9:a156d3de5647 506 }
hudakz 9:a156d3de5647 507
hudakz 9:a156d3de5647 508 /**
hudakz 9:a156d3de5647 509 * @brief
hudakz 9:a156d3de5647 510 * @note
hudakz 9:a156d3de5647 511 * @param
hudakz 9:a156d3de5647 512 * @retval
hudakz 9:a156d3de5647 513 */
hudakz 11:647d53d146f1 514 void Enc28j60Eth::writeBuffer(uint16_t len, uint8_t* data)
hudakz 9:a156d3de5647 515 {
hudakz 9:a156d3de5647 516 _cs = 0;
hudakz 9:a156d3de5647 517
hudakz 9:a156d3de5647 518 // issue write command
hudakz 9:a156d3de5647 519 _spi.write(ENC28J60_WRITE_BUF_MEM);
hudakz 9:a156d3de5647 520 while (len) {
hudakz 9:a156d3de5647 521 len--;
hudakz 9:a156d3de5647 522
hudakz 9:a156d3de5647 523 // write data
hudakz 9:a156d3de5647 524 _spi.write(*data);
hudakz 9:a156d3de5647 525 data++;
hudakz 9:a156d3de5647 526 }
hudakz 9:a156d3de5647 527
hudakz 9:a156d3de5647 528 _cs = 1;
hudakz 9:a156d3de5647 529 }
hudakz 9:a156d3de5647 530
hudakz 9:a156d3de5647 531 /**
hudakz 9:a156d3de5647 532 * @brief
hudakz 9:a156d3de5647 533 * @note
hudakz 9:a156d3de5647 534 * @param
hudakz 9:a156d3de5647 535 * @retval
hudakz 9:a156d3de5647 536 */
hudakz 11:647d53d146f1 537 void Enc28j60Eth::setBank(uint8_t address)
hudakz 9:a156d3de5647 538 {
hudakz 9:a156d3de5647 539 // set the bank (if needed)
hudakz 9:a156d3de5647 540 if ((address & BANK_MASK) != bank) {
hudakz 9:a156d3de5647 541 // set the bank
hudakz 9:a156d3de5647 542 writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1 | ECON1_BSEL0));
hudakz 9:a156d3de5647 543 writeOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK) >> 5);
hudakz 9:a156d3de5647 544 bank = (address & BANK_MASK);
hudakz 9:a156d3de5647 545 }
hudakz 9:a156d3de5647 546 }
hudakz 9:a156d3de5647 547
hudakz 9:a156d3de5647 548 /**
hudakz 9:a156d3de5647 549 * @brief
hudakz 9:a156d3de5647 550 * @note
hudakz 9:a156d3de5647 551 * @param
hudakz 9:a156d3de5647 552 * @retval
hudakz 9:a156d3de5647 553 */
hudakz 11:647d53d146f1 554 uint8_t Enc28j60Eth::readReg(uint8_t address)
hudakz 9:a156d3de5647 555 {
hudakz 9:a156d3de5647 556 // set the bank
hudakz 9:a156d3de5647 557 setBank(address);
hudakz 9:a156d3de5647 558
hudakz 9:a156d3de5647 559 // do the read
hudakz 9:a156d3de5647 560 return readOp(ENC28J60_READ_CTRL_REG, address);
hudakz 9:a156d3de5647 561 }
hudakz 9:a156d3de5647 562
hudakz 9:a156d3de5647 563 /**
hudakz 9:a156d3de5647 564 * @brief
hudakz 9:a156d3de5647 565 * @note
hudakz 9:a156d3de5647 566 * @param
hudakz 9:a156d3de5647 567 * @retval
hudakz 9:a156d3de5647 568 */
hudakz 11:647d53d146f1 569 void Enc28j60Eth::writeReg(uint8_t address, uint8_t data)
hudakz 9:a156d3de5647 570 {
hudakz 9:a156d3de5647 571 // set the bank
hudakz 9:a156d3de5647 572 setBank(address);
hudakz 9:a156d3de5647 573
hudakz 9:a156d3de5647 574 // do the write
hudakz 9:a156d3de5647 575 writeOp(ENC28J60_WRITE_CTRL_REG, address, data);
hudakz 9:a156d3de5647 576 }
hudakz 9:a156d3de5647 577
hudakz 9:a156d3de5647 578 /**
hudakz 9:a156d3de5647 579 * @brief
hudakz 9:a156d3de5647 580 * @note
hudakz 9:a156d3de5647 581 * @param
hudakz 9:a156d3de5647 582 * @retval
hudakz 9:a156d3de5647 583 */
hudakz 11:647d53d146f1 584 void Enc28j60Eth::writeRegPair(uint8_t address, uint16_t data)
hudakz 9:a156d3de5647 585 {
hudakz 9:a156d3de5647 586 // set the bank
hudakz 9:a156d3de5647 587 setBank(address);
hudakz 9:a156d3de5647 588
hudakz 9:a156d3de5647 589 // do the write
hudakz 9:a156d3de5647 590 writeOp(ENC28J60_WRITE_CTRL_REG, address, (data & 0xFF));
hudakz 9:a156d3de5647 591 writeOp(ENC28J60_WRITE_CTRL_REG, address + 1, (data) >> 8);
hudakz 9:a156d3de5647 592 }
hudakz 9:a156d3de5647 593
hudakz 9:a156d3de5647 594 /**
hudakz 9:a156d3de5647 595 * @brief
hudakz 9:a156d3de5647 596 * @note
hudakz 9:a156d3de5647 597 * @param
hudakz 9:a156d3de5647 598 * @retval
hudakz 9:a156d3de5647 599 */
hudakz 11:647d53d146f1 600 void Enc28j60Eth::phyWrite(uint8_t address, uint16_t data)
hudakz 9:a156d3de5647 601 {
hudakz 9:a156d3de5647 602 // set the PHY register address
hudakz 9:a156d3de5647 603 writeReg(MIREGADR, address);
hudakz 9:a156d3de5647 604
hudakz 9:a156d3de5647 605 // write the PHY data
hudakz 9:a156d3de5647 606 writeRegPair(MIWRL, data);
hudakz 9:a156d3de5647 607
hudakz 9:a156d3de5647 608 // wait until the PHY write completes
hudakz 9:a156d3de5647 609 while (readReg(MISTAT) & MISTAT_BUSY) {
hudakz 9:a156d3de5647 610 wait_us(15);
hudakz 9:a156d3de5647 611 }
hudakz 9:a156d3de5647 612 }
hudakz 9:a156d3de5647 613
hudakz 9:a156d3de5647 614 /**
hudakz 9:a156d3de5647 615 * @brief
hudakz 9:a156d3de5647 616 * @note
hudakz 9:a156d3de5647 617 * @param
hudakz 9:a156d3de5647 618 * @retval
hudakz 9:a156d3de5647 619 */
hudakz 11:647d53d146f1 620 uint16_t Enc28j60Eth::phyRead(uint8_t address)
hudakz 9:a156d3de5647 621 {
hudakz 9:a156d3de5647 622 writeReg(MIREGADR, address);
hudakz 9:a156d3de5647 623 writeReg(MICMD, MICMD_MIIRD);
hudakz 9:a156d3de5647 624
hudakz 9:a156d3de5647 625 // wait until the PHY read completes
hudakz 9:a156d3de5647 626 while (readReg(MISTAT) & MISTAT_BUSY) {
hudakz 9:a156d3de5647 627 wait_us(15);
hudakz 9:a156d3de5647 628 } //and MIRDH
hudakz 9:a156d3de5647 629
hudakz 9:a156d3de5647 630 writeReg(MICMD, 0);
hudakz 9:a156d3de5647 631 return(readReg(MIRDL) | readReg(MIRDH) << 8);
hudakz 9:a156d3de5647 632 }
hudakz 9:a156d3de5647 633
hudakz 9:a156d3de5647 634 /**
hudakz 9:a156d3de5647 635 * @brief
hudakz 9:a156d3de5647 636 * @note
hudakz 9:a156d3de5647 637 * @param
hudakz 9:a156d3de5647 638 * @retval
hudakz 9:a156d3de5647 639 */
hudakz 11:647d53d146f1 640 void Enc28j60Eth::clkout(uint8_t clk)
hudakz 9:a156d3de5647 641 {
hudakz 9:a156d3de5647 642 //setup clkout: 2 is 12.5MHz:
hudakz 9:a156d3de5647 643 writeReg(ECOCON, clk & 0x7);
hudakz 9:a156d3de5647 644 }
hudakz 9:a156d3de5647 645
hudakz 9:a156d3de5647 646 // read the revision of the chip:
hudakz 11:647d53d146f1 647 uint8_t Enc28j60Eth::getrev()
hudakz 9:a156d3de5647 648 {
hudakz 9:a156d3de5647 649 return(readReg(EREVID));
hudakz 9:a156d3de5647 650 }
hudakz 9:a156d3de5647 651
hudakz 9:a156d3de5647 652 /**
hudakz 9:a156d3de5647 653 * @brief
hudakz 9:a156d3de5647 654 * @note
hudakz 9:a156d3de5647 655 * @param
hudakz 9:a156d3de5647 656 * @retval
hudakz 9:a156d3de5647 657 */
hudakz 11:647d53d146f1 658 uint16_t Enc28j60Eth::chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len)
hudakz 9:a156d3de5647 659 {
hudakz 9:a156d3de5647 660 uint8_t spdr;
hudakz 9:a156d3de5647 661 uint16_t t;
hudakz 9:a156d3de5647 662 uint16_t i;
hudakz 9:a156d3de5647 663
hudakz 9:a156d3de5647 664 len = setReadPtr(handle, pos, len) - 1;
hudakz 9:a156d3de5647 665 _cs = 0;
hudakz 9:a156d3de5647 666
hudakz 9:a156d3de5647 667 // issue read command
hudakz 9:a156d3de5647 668 spdr = _spi.write(ENC28J60_READ_BUF_MEM);
hudakz 9:a156d3de5647 669 for (i = 0; i < len; i += 2) {
hudakz 9:a156d3de5647 670 // read data
hudakz 9:a156d3de5647 671 spdr = _spi.write(0x00);
hudakz 9:a156d3de5647 672 t = spdr << 8;
hudakz 9:a156d3de5647 673 spdr = _spi.write(0x00);
hudakz 9:a156d3de5647 674 t += spdr;
hudakz 9:a156d3de5647 675 sum += t;
hudakz 9:a156d3de5647 676 if (sum < t) {
hudakz 9:a156d3de5647 677 sum++; /* carry */
hudakz 9:a156d3de5647 678 }
hudakz 9:a156d3de5647 679 }
hudakz 9:a156d3de5647 680
hudakz 9:a156d3de5647 681 if (i == len) {
hudakz 9:a156d3de5647 682 spdr = _spi.write(0x00);
hudakz 9:a156d3de5647 683 t = (spdr << 8) + 0;
hudakz 9:a156d3de5647 684 sum += t;
hudakz 9:a156d3de5647 685 if (sum < t) {
hudakz 9:a156d3de5647 686 sum++; /* carry */
hudakz 9:a156d3de5647 687 }
hudakz 9:a156d3de5647 688 }
hudakz 9:a156d3de5647 689
hudakz 9:a156d3de5647 690 _cs = 1;
hudakz 9:a156d3de5647 691
hudakz 9:a156d3de5647 692 /* Return sum in host byte order. */
hudakz 9:a156d3de5647 693 return sum;
hudakz 9:a156d3de5647 694 }
hudakz 9:a156d3de5647 695
hudakz 9:a156d3de5647 696 /**
hudakz 9:a156d3de5647 697 * @brief
hudakz 9:a156d3de5647 698 * @note
hudakz 9:a156d3de5647 699 * @param
hudakz 9:a156d3de5647 700 * @retval
hudakz 9:a156d3de5647 701 */
hudakz 11:647d53d146f1 702 void Enc28j60Eth::powerOff()
hudakz 9:a156d3de5647 703 {
hudakz 9:a156d3de5647 704 writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN);
hudakz 9:a156d3de5647 705 wait_ms(50);
hudakz 9:a156d3de5647 706 writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_VRPS);
hudakz 9:a156d3de5647 707 wait_ms(50);
hudakz 9:a156d3de5647 708 writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV);
hudakz 9:a156d3de5647 709 }
hudakz 9:a156d3de5647 710
hudakz 9:a156d3de5647 711 /**
hudakz 9:a156d3de5647 712 * @brief
hudakz 9:a156d3de5647 713 * @note
hudakz 9:a156d3de5647 714 * @param
hudakz 9:a156d3de5647 715 * @retval
hudakz 9:a156d3de5647 716 */
hudakz 11:647d53d146f1 717 void Enc28j60Eth::powerOn()
hudakz 9:a156d3de5647 718 {
hudakz 9:a156d3de5647 719 writeOp(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV);
hudakz 9:a156d3de5647 720 wait_ms(50);
hudakz 9:a156d3de5647 721 writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
hudakz 9:a156d3de5647 722 wait_ms(50);
hudakz 9:a156d3de5647 723 }
hudakz 9:a156d3de5647 724
hudakz 9:a156d3de5647 725 /**
hudakz 9:a156d3de5647 726 * @brief
hudakz 9:a156d3de5647 727 * @note
hudakz 9:a156d3de5647 728 * @param
hudakz 9:a156d3de5647 729 * @retval
hudakz 9:a156d3de5647 730 */
hudakz 11:647d53d146f1 731 bool Enc28j60Eth::linkStatus()
hudakz 9:a156d3de5647 732 {
hudakz 9:a156d3de5647 733 return(phyRead(PHSTAT2) & 0x0400) > 0;
hudakz 9:a156d3de5647 734 }