Пример #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);
}
Пример #2
0
void MACWriteTXEndPt( unsigned int _size)
{
    // calc end offset
    unsigned int offsetEnd    = TXSTART_INIT + _size; 
    
    // Set the TXND pointer to correspond to the packet size given
    enc28j60Write(ETXNDL, low(offsetEnd));
    enc28j60Write(ETXNDH, high(offsetEnd));
}
Пример #3
0
/******************************************************************************
 * Function:        void SOCKETWriteBuffer(unsigned char* _buf, unsigned int _size, unsigned int _start)
 *
 * PreCondition:    none
 *
 * Input:           *_buf:  buffer to write data 
 *                  _size:  amount data to write
 *                  _start: socket's buffer start address
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Writes bytes to Socket RX/TX Buffer space
 *
 * Note:            None
 *****************************************************************************/
void SOCKETWriteBuffer(unsigned char* _buf, unsigned int _size, unsigned int _start)
{
    // Set the write pointer to start of socket buffer area
    enc28j60Write(EWRPTL, low(_start));
    enc28j60Write(EWRPTH, high(_start));
    
    // copy the packet into the socket buffer
    enc28j60WriteBuffer(_size, _buf);
    
}
Пример #4
0
/******************************************************************************
 * Function:        void MACDiscardRx(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Marks the last received packet (obtained using
 *                  MACGetHeader())as being processed and frees the buffer
 *                  memory associated with it
 *
 * Note:            Is is safe to call this function multiple times between
 *                  MACGetHeader() calls.  Extra packets won't be thrown away
 *                  until MACGetHeader() makes it available.
 *****************************************************************************/
void MACDiscardRx(void)
{
    // Update Current pointer
    CurrentPacketLocation.Val = NextPacketLocation.Val;
    
    enc28j60Write(ERXRDPTL, NextPacketLocation.Byte.LB);
    enc28j60Write(ERXRDPTH, NextPacketLocation.Byte.HB);

    // decrement the packet counter indicate we are done with this packet
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
}
Пример #5
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);
}
Пример #6
0
/******************************************************************************
 * Function:        void MACMemCopyAsync(FLOW flow, unsigned int destAddr, unsigned int len)
 *
 * PreCondition:    SPI bus must be initialized (done in MACInit()).
 *
 * Input:           destAddr:   Destination address in the Ethernet memory to
 *                              copy to.  If (PTR_BASE)-1 is specified, the 
 *								current EWRPT value will be used instead.
 *                  sourceAddr: Source address to read from.  If (PTR_BASE)-1 is
 *                              specified, the current ERDPT value will be used
 *                              instead.
 *                  len:        Number of bytes to copy
 *
 * Output:          None
 *
 * Side Effects:    Moves read and write pointers. DMA conflict with transmitting and receiving
 *
 * Overview:        Bytes are asynchrnously transfered within the buffer.  Call
 *                  MACIsMemCopyDone() to see when the transfer is complete.
 *
 * Note:            If a prior transfer is already in progress prior to
 *                  calling this function, this function will block until it
 *                  can start this transfer.
 *
 *                  If (PTR_BASE)-1 is used for the sourceAddr or destAddr
 *                  parameters, then that pointer will get updated with the
 *                  next address after the read or write.
 *****************************************************************************/
void DMACopyFrom(FLOW flow, unsigned int sourceAddr, unsigned int len)
{
    unsigned int destAddr = TXSTART_INIT;
    
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_DMAST);
    
    // Defining source address by read or write pointer
    if (flow == RX)
    {
	destAddr = NextPacketLocation.Val;
    }
    else if (flow == TX)
    {
	destAddr = TXSTART_INIT + 1;
        
        // write per-packet control byte (0x00 means use macon3 settings)
        enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
    }
    
    // Source Init Address
    enc28j60Write(EDMASTL, low(sourceAddr));
    enc28j60Write(EDMASTH, high(sourceAddr));
    
    // Source Stop Address
    enc28j60Write(EDMANDL, low((sourceAddr + len))); // + RXD_STATUS_VECTOR_SIZE));
    enc28j60Write(EDMANDH, high((sourceAddr + len))); // + RXD_STATUS_VECTOR_SIZE));
    
    // Destination Init Address
    enc28j60Write(EDMADSTL, low(destAddr));
    enc28j60Write(EDMADSTH, high(destAddr));
    
    // Clear flag
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_DMAIF);
    
    // Execute!
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
    
    if (flow == TX)
    {
        // Set the write pointer to start of transmit buffer area
        enc28j60Write(EWRPTL, low((destAddr - 1)));
        enc28j60Write(EWRPTH, high((destAddr - 1)));
        
        // Set the TXND pointer to correspond to the packet size given
        enc28j60Write(ETXNDL, low(((destAddr - 1) + len)));
        enc28j60Write(ETXNDH, high(((destAddr - 1) + len)));
    }
    
}
Пример #7
0
/******************************************************************************
 * Function:        void MACWriteTXBufferOffset(unsigned char* _buf, unsigned int _size, unsigned int offset_len)
 *
 * PreCondition:    none
 *
 * Input:           *_buf: buffer to write data 
 *                  _size: amount data to write
 *                  offset:memory pointer to write data
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Writes bytes to TX Buffer space and skips offset
 *
 * Note:            None
 *****************************************************************************/
void MACWriteTXBufferOffset(unsigned char* _buf, unsigned int _size, unsigned int offset_len)
{
    // calc offset
    unsigned int offsetStart  = TXSTART_INIT + offset_len;
    unsigned int offsetEnd    = offsetStart + _size; 
    
    // Set the write pointer to start of transmit buffer area
    enc28j60Write(EWRPTL, low(offsetStart));
    enc28j60Write(EWRPTH, high(offsetStart));
    
    // Set the TXND pointer to correspond to the packet size given
    enc28j60Write(ETXNDL, low(offsetEnd));
    enc28j60Write(ETXNDH, high(offsetEnd));
    
    // 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(_size, _buf);
}
Пример #8
0
/******************************************************************************
 * Function:        void MACMemCopyAsync(FLOW flow, unsigned int destAddr, unsigned int len)
 *
 * PreCondition:    SPI bus must be initialized (done in MACInit()).
 *
 * Input:           destAddr:   Destination address in the Ethernet memory to
 *                              copy to.  If (PTR_BASE)-1 is specified, the 
 *								current EWRPT value will be used instead.
 *                  sourceAddr: Source address to read from.  If (PTR_BASE)-1 is
 *                              specified, the current ERDPT value will be used
 *                              instead.
 *                  len:        Number of bytes to copy
 *
 * Output:          None
 *
 * Side Effects:    Moves read and write pointers. DMA conflict with transmitting and receiving
 *
 * Overview:        Bytes are asynchrnously transfered within the buffer.  Call
 *                  MACIsMemCopyDone() to see when the transfer is complete.
 *
 * Note:            If a prior transfer is already in progress prior to
 *                  calling this function, this function will block until it
 *                  can start this transfer.
 *
 *                  If (PTR_BASE)-1 is used for the sourceAddr or destAddr
 *                  parameters, then that pointer will get updated with the
 *                  next address after the read or write.
 *****************************************************************************/
void DMACopyTo(FLOW flow, unsigned int destAddr, unsigned int len)
{
    unsigned int sourceAddr = RXSTART_INIT;
    
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_DMAST);
    
    // Defining source address by read or write pointer
    if (flow == RX)
    {
        if ((CurrentPacketLocation.Val + RXD_STATUS_VECTOR_SIZE) <= RXSTOP_INIT)
        {
            sourceAddr = CurrentPacketLocation.Val + RXD_STATUS_VECTOR_SIZE;
        }
        else
        {
            unsigned int rest = (CurrentPacketLocation.Val + RXD_STATUS_VECTOR_SIZE) - RXSTOP_INIT;
            sourceAddr = rest - 1;
        }
    }
    else if (flow == TX)
    {
	sourceAddr = TXSTART_INIT;
    }
    
    // Source Init Address
    enc28j60Write(EDMASTL, low(sourceAddr));
    enc28j60Write(EDMASTH, high(sourceAddr));
    
    // Source Stop Address
    // Need compensate circular buffer WHEN RX COPY !!!
    unsigned int floatingEnd = (sourceAddr + len);
    if (flow == RX)
    {	
	if (floatingEnd >= RXSTOP_INIT)
	{
	    // Adjusting END for DMA copy
	    // otherwise it will never reach end pointer
	    // and never get it done
	    unsigned int tempEnd = (floatingEnd - RXSTOP_INIT);
	    if (tempEnd > 0) tempEnd--;
	    
	    floatingEnd = tempEnd;
	}
    }
    
    // Source Stop Address
    enc28j60Write(EDMANDL, low(floatingEnd));
    enc28j60Write(EDMANDH, high(floatingEnd));
    
    // Destination Init Address
    enc28j60Write(EDMADSTL, low(destAddr));
    enc28j60Write(EDMADSTH, high(destAddr));
    
    // Clear flag
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_DMAIF);
    
    // Execute!
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
}
Пример #9
0
void network_set_MAC(uint8_t* macaddr)
{
	enc28j60Write(MAADR5, *macaddr++);
	enc28j60Write(MAADR4, *macaddr++);
	enc28j60Write(MAADR3, *macaddr++);
	enc28j60Write(MAADR2, *macaddr++);
	enc28j60Write(MAADR1, *macaddr++);
	enc28j60Write(MAADR0, *macaddr++);
}
Пример #10
0
static void network_init(void) {
	struct uip_eth_addr macaddr;

	net_event = process_alloc_event();

#if CONFIG_DRIVERS_ENC28J60
	// Set our MAC address
	memcpy_P(&macaddr, &mac, sizeof(mac));

	// Set up ethernet
	enc28j60Init(&macaddr);
	enc28j60Write(ECOCON, 0 & 0x7); // Disable clock output
	_delay_ms(10);

	/* Magjack leds configuration, see enc28j60 datasheet, page 11 */
	// LEDA=green LEDB=yellow
	//
	// 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
	enc28j60PhyWrite(PHLCON, 0x476);
	_delay_ms(100);
#endif
#if CONFIG_DRIVERS_ENC424J600
	// Initialise the hardware
	enc424j600Init();

	// Disable clock output and set up LED stretch
	uint16_t econ2 = enc424j600ReadReg(ECON2);
	econ2 |= ECON2_STRCH; // stretch LED duration
	econ2 &= ~(ECON2_COCON3 | ECON2_COCON2 | ECON2_COCON1 | ECON2_COCON0);
	enc424j600WriteReg(ECON2, econ2);

	// Set up LEDs
	uint16_t eidled = enc424j600ReadReg(EIDLED);
	eidled &= 0x00ff; // and-out the high byte (LED config)
	eidled |= EIDLED_LACFG1 | EIDLED_LBCFG2 | EIDLED_LBCFG1;
	enc424j600WriteReg(EIDLED, eidled);

	// Get the MAC address
	enc424j600GetMACAddr(macaddr.addr);
#endif

#if !CONFIG_LIB_CONTIKI_IPV6
	// Set up timers
	timer_set(&arp_timer, CLOCK_SECOND * 10);
#endif

	uip_setethaddr(macaddr);
}
Пример #11
0
//*********************************************************************************************************
//
// Setzt die MAC-Adressse im Enc28j60
//
//*********************************************************************************************************
void nicSetMacAddress( char * MAC)
{
	// write MAC address
	// NOTE: MAC address in ENC28J60 is byte-backward
  	enc28j60Write(MAADR5, MAC[ 0 ] );
	enc28j60Write(MAADR4, MAC[ 1 ] );
	enc28j60Write(MAADR3, MAC[ 2 ] );
	enc28j60Write(MAADR2, MAC[ 3 ] );
	enc28j60Write(MAADR1, MAC[ 4 ] );
	enc28j60Write(MAADR0, MAC[ 5 ] );
}
Пример #12
0
void nicSetMacAddress(uint8_t* macaddr)
{
    // write MAC address
    // NOTE: MAC address in ENC28J60 is byte-backward
    enc28j60Write(MAADR5, *macaddr++);
    enc28j60Write(MAADR4, *macaddr++);
    enc28j60Write(MAADR3, *macaddr++);
    enc28j60Write(MAADR2, *macaddr++);
    enc28j60Write(MAADR1, *macaddr++);
    enc28j60Write(MAADR0, *macaddr++);
}
Пример #13
0
void network_set_MAC(u08* macaddr)
{
	// write MAC address
	// NOTE: MAC address in ENC28J60 is byte-backward
	enc28j60Write(MAADR5, *macaddr++);
	enc28j60Write(MAADR4, *macaddr++);
	enc28j60Write(MAADR3, *macaddr++);
	enc28j60Write(MAADR2, *macaddr++);
	enc28j60Write(MAADR1, *macaddr++);
	enc28j60Write(MAADR0, *macaddr++);
}
Пример #14
0
/******************************************************************************
 * Function:        void MACInitMacAddr(unsigned char *_macadd)
 *
 * PreCondition:    none
 *
 * Input:           none
 *
 * Output:          None
 *
 * Side Effects:    none
 *
 * Overview:        Init ENC28J60 hardware MAC address
 *
 * Note:            None
 *****************************************************************************/
void MACInitMacAddr(unsigned char *_macadd)
{
    // 2.
    
    // write MAC address
    // NOTE: MAC address in ENC28J60 is byte-backward
    enc28j60Write(MAADR5, _macadd[0]);
    enc28j60Write(MAADR4, _macadd[1]);
    enc28j60Write(MAADR3, _macadd[2]);
    enc28j60Write(MAADR2, _macadd[3]);
    enc28j60Write(MAADR1, _macadd[4]);
    enc28j60Write(MAADR0, _macadd[5]);
}
Пример #15
0
/******************************************************************************
 * Function:        void MACInitMacAddr(unsigned char *_macadd)
 *
 * PreCondition:    none
 *
 * Input:           none
 *
 * Output:          None
 *
 * Side Effects:    none
 *
 * Overview:        Init ENC28J60 hardware MAC address
 *
 * Note:            None
 *****************************************************************************/
void MACInitMacAddr(unsigned char *macaddr)
{
    // 2.
	m_macadd = macaddr; //*(&macaddr[0]);
	//m_macadd[3] = 192;
    
    // write MAC address
    // NOTE: MAC address in ENC28J60 is byte-backward
    enc28j60Write(MAADR5, m_macadd[0]);
    enc28j60Write(MAADR4, m_macadd[1]);
    enc28j60Write(MAADR3, m_macadd[2]);
    enc28j60Write(MAADR2, m_macadd[3]);
    enc28j60Write(MAADR1, m_macadd[4]);
    enc28j60Write(MAADR0, m_macadd[5]);
}
Пример #16
0
int main(void)
{
	led_conf();

	network_init();

	CLKPR = (1<<CLKPCE);	//Change prescaler
	CLKPR = (1<<CLKPS0);	//Use prescaler 2
  //clock_prescale_set(2);
	enc28j60Write(ECOCON, 1 & 0x7);	//Get a 25MHz signal from enc28j60

	int i;
	uip_ipaddr_t ipaddr;
	struct timer periodic_timer, arp_timer;

	clock_init();

	timer_set(&periodic_timer, CLOCK_SECOND / 2);
	timer_set(&arp_timer, CLOCK_SECOND * 10);

	uip_init();
	
	struct uip_eth_addr mac = {UIP_ETHADDR0, UIP_ETHADDR1, UIP_ETHADDR2, UIP_ETHADDR3, UIP_ETHADDR4, UIP_ETHADDR5};

	uip_setethaddr(mac);
	simple_httpd_init();
//    httpd_init();

#ifdef __DHCPC_H__
	dhcpc_init(&mac, 6);
#else
    uip_ipaddr(ipaddr, 192,168,2,55);
    uip_sethostaddr(ipaddr);
    uip_ipaddr(ipaddr, 192,168,2,1);
    uip_setdraddr(ipaddr);
    uip_ipaddr(ipaddr, 255,255,255,0);
    uip_setnetmask(ipaddr);

/*	uip_ipaddr(ipaddr, 192,167,0,255);
	uip_sethostaddr(ipaddr);
	uip_ipaddr(ipaddr, 192,167,0,254);
	uip_setdraddr(ipaddr);
	uip_ipaddr(ipaddr, 255,255,0,0);
	uip_setnetmask(ipaddr);
*/
#endif /*__DHCPC_H__*/


	while(1){
		uip_len = network_read();

		if(uip_len > 0) {
			if(BUF->type == htons(UIP_ETHTYPE_IP)){
				uip_arp_ipin();
				uip_input();
				if(uip_len > 0) {
					uip_arp_out();
					network_send();
				}
			}else if(BUF->type == htons(UIP_ETHTYPE_ARP)){
				uip_arp_arpin();
				if(uip_len > 0){
					network_send();
				}
			}

		}else if(timer_expired(&periodic_timer)) {
			timer_reset(&periodic_timer);

			led_blink();

			for(i = 0; i < UIP_CONNS; i++) {
				uip_periodic(i);
				if(uip_len > 0) {
					uip_arp_out();
					network_send();
				}
			}

			#if UIP_UDP
			for(i = 0; i < UIP_UDP_CONNS; i++) {
				uip_udp_periodic(i);
				if(uip_len > 0) {
					uip_arp_out();
					network_send();
				}
			}
			#endif /* UIP_UDP */

			if(timer_expired(&arp_timer)) {
				timer_reset(&arp_timer);
				uip_arp_timer();
			}
		}
	}
return 0;
}
Пример #17
0
int main(void)
{


	network_init();

	//CLKPR = (1<<CLKPCE);	//Change prescaler
	//CLKPR = (1<<CLKPS0);	//Use prescaler 2
	//clock_prescale_set(clock_div_2);
	enc28j60Write(ECOCON, 1 & 0x7);	//Get a 25MHz signal from enc28j60

	uartInit();
	uartSetBaudRate(9600);
	rprintfInit(uartSendByte);

	int i;
	uip_ipaddr_t ipaddr; 
	struct timer periodic_timer, arp_timer;

	clock_init();

	timer_set(&periodic_timer, CLOCK_SECOND / 2);
	timer_set(&arp_timer, CLOCK_SECOND * 10);


	uip_init();
	
	struct uip_eth_addr mac = {UIP_ETHADDR0, UIP_ETHADDR1, UIP_ETHADDR2, UIP_ETHADDR3, UIP_ETHADDR4, UIP_ETHADDR5};

	uip_setethaddr(mac);
	
	// set up the udp data stream
	// configure the target system ip and port
	uip_ipaddr_t target_ipaddr;
	uip_ipaddr(&target_ipaddr, 192,168,0,10);
	udpds_conf(&target_ipaddr, 1000, 1);

#ifdef __DHCPC_H__
	dhcpc_init(&mac, 6);
#else
    uip_ipaddr(ipaddr, 192,168,0,1);
	uip_sethostaddr(ipaddr); 
    uip_ipaddr(ipaddr, 192,168,0,1);
    uip_setdraddr(ipaddr);
    uip_ipaddr(ipaddr, 255,255,255,0);
    uip_setnetmask(ipaddr);
#endif /*__DHCPC_H__*/


	while(1){
		uip_len = network_read(); 
		if(uip_len > 0) {
			if(BUF->type == htons(UIP_ETHTYPE_IP)){  
				uip_arp_ipin();
				uip_input();
				if(uip_len > 0) {
					uip_arp_out();
					network_send();
				}

			}else if(BUF->type == htons(UIP_ETHTYPE_ARP)){
				uip_arp_arpin();
				if(uip_len > 0){
					network_send();
				}
			}

		}else if(timer_expired(&periodic_timer)) {
			timer_reset(&periodic_timer);
			for(i = 0; i < UIP_CONNS; i++) {
				uip_periodic(i);
				if(uip_len > 0) {
					uip_arp_out();
					network_send();
				}
			}

			#if UIP_UDP
			for(i = 0; i < UIP_UDP_CONNS; i++) {
				uip_udp_periodic(i);
				if(uip_len > 0) {
					uip_arp_out();
					network_send();
				}
			}
			#endif /* UIP_UDP */

			if(timer_expired(&arp_timer)) {
				timer_reset(&arp_timer);
				uip_arp_timer();
			}
		}
	}
	return 0;
}
Пример #18
0
/******************************************************************************
 * Function:        void DMACopy(FLOW flow, unsigned int destAddr, unsigned int len)
 *
 * PreCondition:    SPI bus must be initialized (done in MACInit()).
 *
 * Input:           destAddr:   Destination address in the Ethernet memory to
 *                              copy to.  If (PTR_BASE)-1 is specified, the 
 *								current EWRPT value will be used instead.
 *                  sourceAddr: Source address to read from.  If (PTR_BASE)-1 is
 *                              specified, the current ERDPT value will be used
 *                              instead.
 *                  len:        Number of bytes to copy
 *
 * Output:          None
 *
 * Side Effects:    Moves read and write pointers. DMA conflict with transmitting and receiving
 *
 * Overview:        Bytes are asynchrnously transfered within the buffer.  Call
 *                  MACIsMemCopyDone() to see when the transfer is complete.
 *
 * Note:            If a prior transfer is already in progress prior to
 *                  calling this function, this function will block until it
 *                  can start this transfer.
 *
 *                  If (PTR_BASE)-1 is used for the sourceAddr or destAddr
 *                  parameters, then that pointer will get updated with the
 *                  next address after the read or write.
 *****************************************************************************/
void DMACopy(FLOW flow, unsigned int destAddr, unsigned int len)
{
    // finally using tx socket space, after 2 years developing this enc28's EEPROM approach
    // for documentation sake, I have made following organization
    // to enc28's 8k eeprom
    // 0H ~ 800H (2K) - RX FIFO (CYCLIC)
    // 802H ~ 1000H (2K-1byte) - TX FIFO (FLAT)
    // 1002H ~ 1401H - Socket RX Bank 0 (FLAT)
    // 1402H ~ 1801H - Socket RX Bank 1 (not used yet) (FLAT)
    // 1803H ~ 1C02H - Socket TX Bank 0 (FLAT)
    // 1C03H ~ 1FFEH - Socket TX Bank 1 (not used yet) (FLAT) -- Total 8K EEPROM used ONLY by this library!
    // Errata 7b has lots of issues about this addresses
    // I have made them by the book!
    // By Renato Aloi (May 2015)
    // While trying to remmember all rules to implement last and most important option: Write at TX Socket Buffer!
    unsigned int sourceAddr = RXSTART_INIT; // RX Copy From FIFO To Bank
    
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_DMAST);
    
    // Defining source address by read or write pointer
    if (flow == RX)
    {
        if ((CurrentPacketLocation.Val + RXD_STATUS_VECTOR_SIZE) <= RXSTOP_INIT)
        {
            sourceAddr = CurrentPacketLocation.Val + RXD_STATUS_VECTOR_SIZE;
        }
        else
        {
            unsigned int rest = (CurrentPacketLocation.Val + RXD_STATUS_VECTOR_SIZE) - RXSTOP_INIT;
            sourceAddr = rest - 1;
        }
    }
    else if (flow == TX)
    {
	sourceAddr = SOCKET_TX_START(0); // TX Copy From Bank To FIFO
    }
    
    // Source Init Address
    enc28j60Write(EDMASTL, low(sourceAddr));
    enc28j60Write(EDMASTH, high(sourceAddr));
    
    // Source Stop Address
    // Need compensate circular buffer WHEN RX COPY !!!
    unsigned int floatingEnd = (sourceAddr + len);
    if (flow == RX)
    {	
	if (floatingEnd >= RXSTOP_INIT)
	{
	    // Adjusting END for DMA copy
	    // otherwise it will never reach end pointer
	    // and never get it done
	    unsigned int tempEnd = (floatingEnd - RXSTOP_INIT);
	    if (tempEnd > 0) tempEnd--;
	    
	    floatingEnd = tempEnd;
	}
    }
    
    // Source Stop Address
    enc28j60Write(EDMANDL, low(floatingEnd));
    enc28j60Write(EDMANDH, high(floatingEnd));
    
    // Destination Init Address
    enc28j60Write(EDMADSTL, low(destAddr));
    enc28j60Write(EDMADSTH, high(destAddr));
    
    // Clear flag
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_DMAIF);
    
    // Execute!
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
}
Пример #19
0
int main(void)
{

	network_init();
	// network.c
	// enc28j60Init();
	// enc28j60PhyWrite(PHLCON,0x476);

	//CLKPR = (1<<CLKPCE);	//Change prescaler
	//CLKPR = (1<<CLKPS0);	//Use prescaler 2
	//clock_prescale_set(clock_div_2);
	enc28j60Write(ECOCON, 1 & 0x7);	
	// enc28j60.c
	//Get a 25MHz signal from enc28j60

	#ifdef MY_DEBUG
	uartInit();
	uartSetBaudRate(9600);
	rprintfInit(uartSendByte);
	#endif

	int i;
	uip_ipaddr_t ipaddr; // uip.h 
	// typedef u16_t uip_ip4addr_t[2]; 
	// typedef uip_ip4addr_t uip_ipaddr_t;
	struct timer periodic_timer, arp_timer;

	clock_init();


	timer_set(&periodic_timer, CLOCK_SECOND / 2);
	timer_set(&arp_timer, CLOCK_SECOND * 10);

	uip_init();
	// uip.c

	//uip_arp_init();
	// uip_arp.c
	// must be done or sometimes arp doesn't work
	
	struct uip_eth_addr mac = {UIP_ETHADDR0, UIP_ETHADDR1, UIP_ETHADDR2, UIP_ETHADDR3, UIP_ETHADDR4, UIP_ETHADDR5};

	uip_setethaddr(mac);

	simple_httpd_init();

#ifdef __DHCPC_H__
	dhcpc_init(&mac, 6);
#else
    uip_ipaddr(ipaddr, 192,168,0,1); // uip.h
	uip_sethostaddr(ipaddr); // uip.h
	// #define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr))
    uip_ipaddr(ipaddr, 192,168,0,1);
    uip_setdraddr(ipaddr);
	// #define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr))
    uip_ipaddr(ipaddr, 255,255,255,0);
    uip_setnetmask(ipaddr);
	// #define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr))

#endif /*__DHCPC_H__*/


	while(1){

		uip_len = network_read(); 
		// uip.c : u16_t uip_len;
		// network.c : return ((unt16_t) enc28j60PacketReceive(UIP_BUFSIZE, (uint8_t *)uip_buf)); 
		// enc28j60.c : enc28j60PacketReceive
		// uip.c : uint8_t uip_buf[UIP_BUFSIZE+2]; 
		// uipconf.h : UIP_BUFSIZE:300
		if(uip_len > 0) {
			if(BUF->type == htons(UIP_ETHTYPE_IP)){  
			#ifdef MY_DEBUG
			//rprintf("eth in : uip_len = %d, proto = %d\n", uip_len, uip_buf[23]);
			//debugPrintHexTable(uip_len, uip_buf);
			#endif
			// struct uip_eth_hdr {
			//	struct uip_eth_addr dest;
			//	struct uip_eth_addr src;
			//	u16_t type;
			//	};
			// struct uip_eth_addr { // Representation of a 48-bit Ethernet address
			// 	u8_t addr[6];
			// };
			//	http://www.netmanias.com/ko/post/blog/5372/ethernet-ip-tcp-ip/packet-header-ethernet-ip-tcp-ip
			//	UIP_ETHTYPE_IP(0x0800) : IPv4 Packet(ICMP, TCP, UDP)
				uip_arp_ipin();
				#ifdef MY_DEBUG
				//rprintf("ip in : uip_len = %d, proto = %d\n", uip_len, uip_buf[23]);
				//debugPrintHexTable(uip_len, uip_buf+14);
				#endif
				// uip_arp.c
				// #define IPBUF ((struct ethip_hdr *)&uip_buf[0])
				// struct ethip_hdr {
				// 	 struct uip_eth_hdr ethhdr;
				// 	 // IP header
				// 	 u8_t vhl,
				// 	 	tos,
				// 	 	len[2],
				// 	 	ipid[2],
				// 	 	ipoffset[2],
				// 	 	ttl,
				// 	 	proto; // ICMP: 1, TCP: 6, UDP: 17
				// 	 u16_t ipchksum;
				// 	 u16_t srcipaddr[2],
				// 	 destipaddr[2];
				// }
				// if ((IBUF->srcipaddr & uip_netmask) != uip_hostaddr & (uip_netmask)) return;
				// uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
				uip_input();
				#ifdef MY_DEBUG
				//rprintf("ip out : uip_len = %d, proto = %d\n", uip_len, uip_buf[23]);
				//debugPrintHexTable(uip_len, uip_buf+14);
				#endif
				// ip out packet
				// eg ICMP 
				// uip_len : 84
				// source ip <-> destination ip
				// type : 8 (Echo (ping) request) -> 0 (Echo (ping) reply)
				// uip.h
				// #define uip_input()        uip_process(UIP_DATA) // UIP_DATA(1) : Tells uIP that there is incoming
				// uip_process : The actual uIP function which does all the work.
				if(uip_len > 0) {
					uip_arp_out();
					#ifdef MY_DEBUG
					//rprintf("ip out : uip_len = %d, proto = %d\n", uip_len, uip_buf[23]);
					//debugPrintHexTable(uip_len, uip_buf);
					#endif
					// Destination MAC Address <=> Source MAC Address
					// w/o Ethernet CRC
					// uip_arp.c

					network_send();
					// network.c
					// if(uip_len <= UIP_LLH_LEN + 40){ // UIP_LLH_LEN : 14
					// 	enc28j60PacketSend(uip_len, (uint8_t *)uip_buf, 0, 0);
					// }else{
					// enc28j60PacketSend(54, (uint8_t *)uip_buf , uip_len - UIP_LLH_LEN - 40, (uint8_t*)uip_appdata);
					// }
				}
			}else if(BUF->type == htons(UIP_ETHTYPE_ARP)){
				// UIP_ETHYPE_ARP(0x0806)
				#ifdef MY_DEBUG
				//rprintf("arp in : uip_len = %d\n", uip_len);
				//debugPrintHexTable(uip_len, uip_buf);
				#endif
				// arp in : 64 bytes
				uip_arp_arpin();
				if(uip_len > 0){ // always uip_len > 0
					#ifdef MY_DEBUG
					//rprintf("ip in : uip_len = %d\n", uip_len);
					//debugPrintHexTable(uip_len, uip_buf);
					#endif
					// arp out : 42 bytes
					// 64 - Ethernet_padding(18) - Ethernet_CRC(4)
					// Send MAC address <--> Target MAC address
					// Send IP address <--> Target IP address
					// uip_arp.c
					network_send();
				}
			}

		}else if(timer_expired(&periodic_timer)) {

			timer_reset(&periodic_timer);

			for(i = 0; i < UIP_CONNS; i++) {
				uip_periodic(i);
                // uip.h
                // #define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
                // uip_process(UIP_UDP_TIMER); } while (0) // UIP_UDP_TIMER : 5
                // uip.c; uip_process
                // if(flag == UIP_UDP_TIMER) {
                //  if(uip_udp_conn->lport != 0) {
                //      uip_conn = NULL;
                //      uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
                //      uip_len = uip_slen = 0;
                //      uip_flags = UIP_POLL;
                //      UIP_UDP_APPCALL();
                //      goto udp_send;
                //  }
                // } else {
                //  goto drop;
                // }
				if(uip_len > 0) {
					uip_arp_out();
					network_send();
				}
			}

			#if UIP_UDP
			for(i = 0; i < UIP_UDP_CONNS; i++) {
				uip_udp_periodic(i);
				if(uip_len > 0) {
					uip_arp_out();
					network_send();
				}
			}
			#endif /* UIP_UDP */

			if(timer_expired(&arp_timer)) {
				timer_reset(&arp_timer);
				uip_arp_timer();
			}
		}
	}
	return 0;
}
Пример #20
0
/******************************************************************************
 * Function:        void SOCKETSetTxPointer(unsigned int addr)
 *
 * PreCondition:    none
 *
 * Input:           addr = Address to set TX pointer to.
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Sets TX pointer location
 *
 * Note:            None
 *****************************************************************************/
void SOCKETSetTxPointer(unsigned int addr)
{
    enc28j60Write(EWRPTL, low(addr));
    enc28j60Write(EWRPTH, high(addr));
}
Пример #21
0
/******************************************************************************
 * Function:        void MACInit(void)
 *
 * PreCondition:    none
 *
 * Input:           none
 *
 * Output:          None
 *
 * Side Effects:    none
 *
 * Overview:        Init. ENC28J60 hardware
 *
 * Note:            None
 *****************************************************************************/
void MACInit(void)
{
    // 1.
    
    NextPacketLocation.Val = 0;
    CurrentPacketLocation.Val = 0;
    
    // RESET the entire ENC28J60, clearing all registers
    MACSendSystemReset();
    
    // Start up in Bank 0 and configure the receive buffer boundary pointers
    // and the buffer write protect pointer (receive buffer read pointer)
    NextPacketLocation.Val = RXSTART_INIT;
    CurrentPacketLocation.Val = RXSTART_INIT;

    enc28j60Write(ERXSTL, low(RXSTART_INIT));
    enc28j60Write(ERXSTH, high(RXSTART_INIT));
    enc28j60Write(ERXRDPTL, low(RXSTART_INIT));    // Write low byte first
    enc28j60Write(ERXRDPTH, high(RXSTART_INIT));   // Write high byte last
    enc28j60Write(ERXNDL, low(RXSTOP_INIT));
    enc28j60Write(ERXNDH, high(RXSTOP_INIT));
    enc28j60Write(ETXSTL, low(TXSTART_INIT));
    enc28j60Write(ETXSTH, high(TXSTART_INIT));

    // Enter Bank 1 and configure Receive Filters
    // 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);
    enc28j60Write(EPMM0, 0x3F);
    enc28j60Write(EPMM1, 0x30);
    enc28j60Write(EPMCSL, 0xF9);
    enc28j60Write(EPMCSH, 0xF7);    
    // promiscuous mode
    //enc28j60Write(ERXFCON, ERXFCON_CRCEN);
    
    // Disable the CLKOUT output to reduce EMI generation
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECOCON, 0x00);   // Output off (0V)
    //enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECOCON, 0x01); // 25.000MHz
    //enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECOCON, 0x03); // 8.3333MHz (*4 with PLL is 33.3333MHz)
    
    // Enable the receive portion of the MAC
    // full duplex
    //enc28j60Write(MACON1, (MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS));
    // half duplex
    enc28j60Write(MACON1, MACON1_MARXEN);
    
    // bring MAC out of reset
    enc28j60Write(MACON2, 0x00);
    
    // Pad packets to 60 bytes, add CRC, and check Type/Length field.
    // full duplex
    //enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3,
    //                MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN | MACON3_FULDPX);
    // half duplex
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3,
                   MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN);
    
    // Allow infinite deferals if the medium is continuously busy
    // (do not time out a transmission if the half duplex medium is
    // completely saturated with other people's data)
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON4, MACON4_DEFER);
    // Clear because we are in full duplex mode
    //enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, MACON4, MACON4_DEFER);
    
    // Set the maximum packet size which the controller will accept
    unsigned int limit = 1518;  // 6+6+2+1500+4
                                // 1518 is the IEEE 802.3 specified limit
    enc28j60Write(MAMXFLL, low(limit));  
    enc28j60Write(MAMXFLH, high(limit));
    
    // set inter-frame gap (back-to-back)
    // half duplex
    enc28j60Write(MABBIPG, 0x12);
    // full duplex
    //enc28j60Write(MABBIPG, 0x15);
    
    // set inter-frame gap (non-back-to-back)
    enc28j60Write(MAIPGL, 0x12);
    // half duplex
    enc28j60Write(MAIPGH, 0x00);
    // full duplex
    //enc28j60Write(MAIPGH, 0x0C);

    // Late collisions occur beyond 63+8 bytes (8 bytes for preamble/start of frame delimiter)
    // 55 is all that is needed for IEEE 802.3, but ENC28J60 B5 errata for improper link pulse
    // collisions will occur less often with a larger number.
    enc28j60Write(MACLCON2, 63);
    
}