Beispiel #1
0
/******************************************************************************
 * Function:        void MACReadRXBuffer(unsigned char* _buf, unsigned int _size)
 *
 * PreCondition:    none
 *
 * Input:           *_buf: buffer to write data read
 *                  _size: amount data to read
 *
 * Output:          None
 *
 * Side Effects:    Last packet is discarded if MACDiscardRx() hasn't already
 *                  been called.
 *
 * Overview:        None
 *
 * Note:            None
 *****************************************************************************/
void MACReadRXBuffer(unsigned char* _buf, unsigned int _size)
{
    uint16_t rxstat;
    uint16_t len;
    
    // Set the read pointer to the start of the received packet
    enc28j60Write(ERDPTL, CurrentPacketLocation.Byte.LB);
    enc28j60Write(ERDPTH, CurrentPacketLocation.Byte.HB);
    
    // read the next packet pointer
    NextPacketLocation.Byte.LB  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
    NextPacketLocation.Byte.HB  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
    
    // read the packet length (see datasheet page 43)
    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  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
    rxstat |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;
    
    // limit retrieve length
    if (len > _size) len = _size;
    
    // copy the packet from the receive buffer
    enc28j60ReadBuffer(len, _buf);
}
Beispiel #2
0
void vram_read(U8 pointer, U8 *data, U8 len)
{
	// Set the write pointer to start of transmit buffer area
	enc28j60WriteWord(ERDPTL, vramBUF_start + pointer);

	// Read bytes
	enc28j60ReadBuffer(len, data);
}
Beispiel #3
0
U8 vram_read(U8 pointer)
{
	U8 data;
	
	// Set the write pointer to start of transmit buffer area
	enc28j60WriteWord(ERDPTL, vramBUF_start + pointer);

	// Read a byte
	enc28j60ReadBuffer(1, &data);
	return data;
}
Beispiel #4
0
/******************************************************************************
 * Function:        void SOCKETReadBuffer(unsigned char* _buf, unsigned int _size, unsigned int _start)
 *
 * PreCondition:    none
 *
 * Input:           *_buf:  buffer to write data read
 *                  _size:  amount data to read
 *                  _start: socket's buffer start address
 *
 * Output:          None
 *
 * Side Effects:    interfere in ERDPT pointer
 *
 * Overview:        Reads bytes from Socket RX/TX Buffer space
 *
 * Note:            None
 *****************************************************************************/
void SOCKETReadBuffer(unsigned char* _buf, unsigned int _size, unsigned int _start)
{
    // Set the read pointer to the start of the packet kept in the socket buffer
    enc28j60Write(ERDPTL, low(_start));
    enc28j60Write(ERDPTH, high(_start));
    
    //delay(1);
    
    // copy the packet from the socket buffer
    enc28j60ReadBuffer(_size, _buf);
}
Beispiel #5
0
static word enc28j60ReadBufferWord() {
    word result;
    enc28j60ReadBuffer(2, (byte*) &result);
    return result;
}
Beispiel #6
0
/**
 * Should allocate a pbuf and transfer the bytes of the incoming
 * packet from the interface into the pbuf.
 *
 * @param netif the lwip network interface structure for this ethernetif
 * @return a pbuf filled with the received packet(including MAC header)
 *         NULL on memory error
 */
static struct pbuf *
low_level_input(struct netif *netif)
{
  struct ethernetif *ethernetif = netif->state;
  struct pbuf *p, *q;
  u16_t len;

	uint8_t b = enc28j60ReadControl(EPKTCNT);
	// myprintf("c: %d\r\n", b);
	if (b == 0)
		return 0;

	if (dodump)
		myprintf(COLOR_YELLOW "----- RECEIVING ----- \r\n" COLOR_OFF);

	uint16_t curPtr = ethNextPacketPtr;
	// myprintf("@1");
	enc28j60WriteControlWordCheck(ERDPTL, curPtr);

	uint16_t nextPtr, packetSize, status1, status2;

	if (dodump)
		enc28j60PrintMemory();

	ENC28J60_RXSTATUS status;
	enc28j60ReadBuffer(status.d, 6);

	nextPtr = status.bits.NextPacket;
	ethNextPacketPtr = nextPtr;
	packetSize = status.bits.ByteCount - 4;

	if (dodump)
		enc28j60PrintRXStatus(&status);	
	// myprintf("in\r\n");
	// myprintf("STATUS: "); 
	// myprintf("data len: %u cur ptr %u next ptr: %u\r\n", packetSize, curPtr, nextPtr);

	// myprintf("recv %d\r\n", len);

		// PrintMemory();

	/* Obtain the size of the packet and put it into the "len"
     variable. */
  // len = enc28j60BeginPacketReceive();
	// if (!len) return NULL;

#if ETH_PAD_SIZE
  len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
#endif

	// myprintf("aclloc :%d\r\n", len);
  /* We allocate a pbuf chain of pbufs from the pool. */
  p = pbuf_alloc(PBUF_RAW, packetSize, PBUF_POOL);
  
	// myprintf("c: %d\r\n", pbuf_clen(p));
	// p=0;
  if (p != NULL)
	{

#if ETH_PAD_SIZE
    pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif

    /* We iterate over the pbuf chain until we have read the entire
     * packet into the pbuf. */
		// int len2=packetSize;
    for (q = p; q; q = q->next) {
      /* Read enough bytes to fill this pbuf in the chain. The
       * available data in the pbuf is given by the q->len
       * variable. */
			enc28j60ReadBuffer(q->payload, q->len);

			// if (q->len == p->tot_len) break;
		}

		//acknowledge that packet has been read();
		// enc28j60EndPacketReceive();

#if ETH_PAD_SIZE
    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif

    LINK_STATS_INC(link.recv);
  } else {
    //drop packet();
		// enc28j60EndPacketReceive();
    LINK_STATS_INC(link.memerr);
    LINK_STATS_INC(link.drop);
  }

	// enc28j60SetBits(ECON1, ECON1_RXEN);

	if (ethNextPacketPtr == RXStart)
	{
		// if (nextPacketPtr - 1 < RXStart || nextPacketPtr - 1 > RXEnd)
		// myprintf("@2");
		enc28j60WriteControlWordCheck(ERXRDPTL, RXEnd);
		myprintf("nextPtr == RXStart!\r\n");
		// for (;;);
	}
	else
	{
		// myprintf("@3");
		enc28j60WriteControlWordCheck(ERXRDPTL, ethNextPacketPtr - 1);
	}

	enc28j60SetBits(ECON2, ECON2_PKTDEC);

	if (dodump)
		myprintf(COLOR_YELLOW "----- RECEIVING END ----- \r\n" COLOR_OFF);
	// b = enc28j60ReadControl(EPKTCNT);

	// pbuf_free(p); return 0;
  return p;
}
Beispiel #7
0
/**
 * This function should do the actual transmission of the packet. The packet is
 * contained in the pbuf that is passed to the function. This pbuf
 * might be chained.
 *
 * @param netif the lwip network interface structure for this ethernetif
 * @param p the MAC packet to send(e.g. IP packet including MAC addresses and type)
 * @return ERR_OK if the packet could be sent
 *         an err_t value if the packet couldn't be sent
 *
 * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
 *       strange results. You might consider waiting for space in the DMA queue
 *       to become availale since the stack doesn't retry to send a packet
 *       dropped because of memory failure(except for the TCP timers).
 */
static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
	struct ethernetif *ethernetif = netif->state;
  struct pbuf *q;

	// return;
#if ETH_PAD_SIZE
  pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif

	uint8_t b = enc28j60ReadControl(EIR);
	if (b & EIR_TXERIF)
	{
		myprintf("TXERIF\r\n");

		enc28j60SetBits(ECON1, ECON1_TXRST);
		enc28j60ClearBits(ECON1, ECON1_TXRST);
		enc28j60ClearBits(EIR, EIR_TXERIF);

		// for (;;);
	}

retry:
	if (dodump)
		myprintf(COLOR_GREEN "----- SENDING ----- \r\n" COLOR_OFF);

	if (dodump)
		myprintf("@4");
	enc28j60WriteControlWordCheck(EWRPTL, TXStart);
	uint16_t end = TXStart + 1 + p->tot_len;
	if (dodump)
		myprintf("@5");
	enc28j60WriteControlWordCheck(ETXSTL, TXStart);
	if (dodump)
		myprintf("@6");
	enc28j60WriteControlWordCheck(ETXNDL, end);

	enc28j60_enableChip();
	enc28j60_rw(CMD_WRITE_BUFFER_MEMORY);
	enc28j60_rw(0x00); // control byte
	for (q = p; q; q = q->next)
	{
		int i;
		for (i = 0; i < q->len; i++)
			enc28j60_rw(((char*)q->payload)[i]);
		if (q->len == p->tot_len)
			break;
  }
	enc28j60_disableChip();


	// myprintf("a %d\r\n", p->tot_len);
	// enc28j60PrintMemory();

	enc28j60SetBits(ECON1, ECON1_TXRTS);

	static int totalFails = 0;
	myprintf("waiting until packet is sent (fails: %d)\r\n", totalFails);
	b = enc28j60ReadControl(ECON1);
	uint32_t startTime = ticks;
	while (b & ECON1_TXRTS)
	{
		myprintf("TRANS 0x%02x\r\n", b);
		_delay_ms(10);
		if (ticks - startTime > 100)
		{
			totalFails++;
			enc28j60SetBits(ECON1, ECON1_TXRST);
			enc28j60ClearBits(ECON1, ECON1_TXRST);
			goto retry;
		}
		b = enc28j60ReadControl(ECON1);
	}
	myprintf("packet sent\r\n");

	// enc28j60ClearBits(ECON1, ECON1_TXRTS);

	b = enc28j60ReadControl(ESTAT);
	// myprintf("ESTAT: "); enc28j60PrintESTAT(b);
	if (dodump)
		myprintf("@7");
	enc28j60WriteControlWordCheck(ERDPTL, end + 1);
	ENC28J60_TXSTATUS txstatus;
	enc28j60ReadBuffer(txstatus.d,7);

	if (dodump)
		enc28j60PrintTXStatus(&txstatus);

	if (b & ESTAT_TXABRT)
	{
		myprintf("TXABRT\r\n");
		if (txstatus.bits.LateCollision)
		{
			enc28j60SetBits(ECON1, ECON1_TXRST);
			enc28j60ClearBits(ECON1, ECON1_TXRST);
			enc28j60ClearBits(ESTAT, ESTAT_TXABRT | ESTAT_LATECOL);
		}
	}

	enc28j60ClearBits(EIR, EIR_TXERIF | EIR_TXIF);
	enc28j60ClearBits(ESTAT, ESTAT_TXABRT);

	if (dodump)
		myprintf(COLOR_GREEN "----- SENDING END ----- \r\n" COLOR_OFF);
	// uint16_t sentBytes = *((uint16_t*)d + 0);
	// myprintf("send bytes: %d\r\n", sentBytes);

	// int i; for (i=0;i<7;i++) myprintf("0x%02x, ", d[i]); myprintf("\r\n");


	// enc28j60BeginPacketSend(p->tot_len);

  // for (q = p; q != NULL; q = q->next) {
    // /* Send the data from the pbuf to the interface, one pbuf at a
       // time. The size of the data in each pbuf is kept in the ->len
       // variable. */
		// enc28j60PacketSend(q->payload, q->len);
  // }
	// enc28j60EndPacketSend();

#if ETH_PAD_SIZE
  pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
  
  LINK_STATS_INC(link.xmit);

  return ERR_OK;
}