⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 w3150a.c

📁 W3510A PPPoE code for network use
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * (c)COPYRIGHT
 * ALL RIGHT RESERVED
 *
 * FileName : w3150a.c
 * Revision History :
 * ----------  -------  -----------  ---------------------------------------------
 * Date        version  Name         Description
 * ----------  -------  -----------  ---------------------------------------------
 * 09/23/2005  1.0      Bong         Create version
 * ----------  -------  -----------  ---------------------------------------------
 * 10/12/2005  2.0      Woo          Release version
 * ----------  -------  -----------  ---------------------------------------------
 * 10/13/2005  2.0.1    Bong         added function getting GW_IP, GW_MAC for UDP defection
 * ----------  -------  -----------  ---------------------------------------------
 * 10/25/2005  2.0.2    Bong         added function fix subnet bug.
 * ----------  -------  -----------  ---------------------------------------------
 * 11/03/2005  2.0.3    Bong         modify issubnet() function.
 * ----------  -------  -----------  ---------------------------------------------
 * 11/22/2005  2.0.4    Bong         #define _20051121_
 *                                   modify pppinit_in() function.
 *                                   support CHAP mode
 *                                   added md5.c, md5.h
 * ----------  -------  -----------  ---------------------------------------------
 * 
 * last update : 11/03/2005
 */

//#ifdef __DEF_IINCHIP_PPP__
   #define _20051121_ /* chap included */
//#endif

#include "w3150a.h"
#include "../mcu/delay.h" // for wait function

//#ifdef __DEF_IINCHIP_PPP__
   #ifdef _20051121_ /* chap included */
      #include "md5.h"
   #endif
//#endif

uint8 L_IP[4]; // local ip
uint8 SUBNET[4]; // subnet
uint8 GW_IP[4]; // gateway ip address
uint8 GW_MAC[6]; // gateway mac address
// 2005.10.25 added fix subnet check error
uint8 is_gw_samenet;
uint8 I_STATUS[MAX_SOCK_NUM];
uint16 SMASK[MAX_SOCK_NUM]; /* Variable for Tx buffer MASK in each channel */
uint16 RMASK[MAX_SOCK_NUM]; /* Variable for Rx buffer MASK in each channel */
uint16 SSIZE[MAX_SOCK_NUM]; /* Max Tx buffer size by each channel */
uint16 RSIZE[MAX_SOCK_NUM]; /* Max Rx buffer size by each channel */
uint16 SBUFBASEADDRESS[MAX_SOCK_NUM]; /* Tx buffer base address by each channel */
uint16 RBUFBASEADDRESS[MAX_SOCK_NUM]; /* Rx buffer base address by each channel */

uint8 getISR(uint8 s)
{
   return I_STATUS[s];
}
uint16 getIINCHIP_RxMAX(uint8 s)
{
   return RSIZE[s];
}
uint16 getIINCHIP_TxMAX(uint8 s)
{
   return SSIZE[s];
}
uint16 getIINCHIP_RxMASK(uint8 s)
{
   return RMASK[s];
}
uint16 getIINCHIP_TxMASK(uint8 s)
{
   return SMASK[s];
}
uint16 getIINCHIP_RxBASE(uint8 s)
{
   return RBUFBASEADDRESS[s];
}
uint16 getIINCHIP_TxBASE(uint8 s)
{
   return SBUFBASEADDRESS[s];
}

uint8 IINCHIP_WRITE(uint16 addr,uint8 data)
{
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
	*((vuint8*)(addr)) = data;
#else
	IINCHIP_ISR_DISABLE();
	*((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
	*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
	*((vuint8*)IDM_DR)  = data;
	IINCHIP_ISR_ENABLE();
#endif
	return 1;
}

uint8 IINCHIP_READ(uint16 addr)
{
	uint8 data;
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
	data = *((vuint8*)(addr));
#else   
	IINCHIP_ISR_DISABLE();
	*((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
	*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
	data = *((vuint8*)IDM_DR);
	IINCHIP_ISR_ENABLE();
#endif
	return data;
}

uint16 wiz_write_buf(uint16 addr,uint8* buf,uint16 len)
{
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
   	memcpy((uint8 *)addr, buf, len);
#else
	uint16 idx = 0;
	IINCHIP_ISR_DISABLE();
	*((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
	*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
	for (idx = 0; idx < len ; idx++) *((vuint8*)IDM_DR) = buf[idx];
	IINCHIP_ISR_ENABLE();
#endif
	return len;
}

uint16 wiz_read_buf(uint16 addr, uint8* buf,uint16 len)
{
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
	memcpy(buf, (uint8 *)addr, len);
#else
	uint16 idx = 0;
	IINCHIP_ISR_DISABLE();
	*((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
	*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
	for (idx = 0; idx < len ; idx++) buf[idx] = *((vuint8*)IDM_DR);
	IINCHIP_ISR_ENABLE();
#endif
	return len;
}

/*
* socket interrupt routine
*/
void iinchip_irq(void)
{
#ifdef __DEF_IINCHIP_INT__
	uint8 int_val;
	IINCHIP_ISR_DISABLE();
	int_val = IINCHIP_READ(INT_REG);

	if (int_val & INT_IPCONFLICT)
	{
		printf("IP conflict : %.2x\r\n", int_val);
	}
	if (int_val & INT_UNREACH)
	{
		printf("INT Port Unreachable : %.2x\r\n", int_val);
		printf("UNREACH_IP : %d.%d.%d.%d\r\n", IINCHIP_READ(UNREACH_IP), IINCHIP_READ(UNREACH_IP+1), IINCHIP_READ(UNREACH_IP+2), IINCHIP_READ(UNREACH_IP+3));
		printf("UNREACH_PORT : %.2x %.2x\r\n", IINCHIP_READ(UNREACH_PORT), IINCHIP_READ(UNREACH_PORT+1));
	}

	if (int_val & INT_CH(0))
	{
		I_STATUS[0] = IINCHIP_READ(INT_STATUS(0));
	}
	else if (int_val & INT_CH(1))
	{
		I_STATUS[1] = IINCHIP_READ(INT_STATUS(1));
	}
	else if (int_val & INT_CH(2))
	{
		I_STATUS[2] = IINCHIP_READ(INT_STATUS(2));
	}
	else if (int_val & INT_CH(3))
	{
		I_STATUS[3] = IINCHIP_READ(INT_STATUS(3));
	}
	IINCHIP_ISR_ENABLE();
	
#endif
}

/*
* Initializes the iinchip
* This function is for resetting of the iinchip.
*/
void iinchip_init(void)
{
	*((volatile uint8*)(TMODE)) = TMODE_SWRESET;

#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
	*((volatile uint8*)(TMODE)) = TMODE_INDIRECT | TMODE_AUTOINC;
#ifdef __DEF_IINCHIP_DBG__	
	printf("tmode value is %d \r\n",IINCHIP_READ(TMODE));
#endif	
#endif
}

/**
 * Set the flexible memory
 * This function sets the Tx, Rx memory size by each channel
 * \param tx_size Tx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte)
 * \param rx_size Rx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte)
 * \note
 * bit 1-0 : memory size of channel #0 \n
 * bit 3-2 : memory size of channel #1 \n
 * bit 5-4 : memory size of channel #2 \n
 * bit 7-6 : memory size of channel #3 \n
 * Maximum memory size for Tx, Rx in the W3150 is 8K Bytes,
 * In the range of 8KBytes, the memory size could be allocated dynamically by each channel.
 * Be attentive to sum of memory size shouldn't exceed 8Kbytes
 * and to data transmission and receiption from non-allocated channel may cause some problems.
 * If the 8KBytes memory is already  assigned to centain channel, 
 * other 3 channels couldn't be used, for there's no available memory.
 * If two 4KBytes memory are assigned to two each channels, 
 * other 2 channels couldn't be used, for there's no available memory.
 *
 */
void sysinit(uint8 tx_size, uint8 rx_size)
{
	int16 i;
	int16 ssum,rsum;

#ifdef __DEF_IINCHIP_DBG__
	printf("meminit()\r\n");
#endif

	ssum = 0;
	rsum = 0;
	
	IINCHIP_WRITE(TX_DMEM_SIZE,tx_size); /* Set Tx memory size for each channel */
	IINCHIP_WRITE(RX_DMEM_SIZE,rx_size);	 /* Set Rx memory size for each channel */

	SBUFBASEADDRESS[0] = (uint16)(__DEF_IINCHIP_MAP_TXBUF__);		/* Set base address of Tx memory for channel #0 */
	RBUFBASEADDRESS[0] = (uint16)(__DEF_IINCHIP_MAP_RXBUF__);		/* Set base address of Rx memory for channel #0 */

#ifdef __DEF_IINCHIP_DBG__
	printf("Channel : SEND MEM SIZE : RECV MEM SIZE\r\n");
#endif

	for (i = 0 ; i < MAX_SOCK_NUM; i++)			/* Set maximum memory size for Tx and Rx, mask, base address of memory by each channel */
	{
		SSIZE[i] = (int16)(0);
		RSIZE[i] = (int16)(0);
		if (ssum < 8192)
		{
			switch((tx_size >> i*2) & 0x03)	/* Set maximum Tx memory size */
			{
			case 0:
				SSIZE[i] = (int16)(1024);
				SMASK[i] = (uint16)(0x03FF);
				break;
			case 1:
				SSIZE[i] = (int16)(2048);
				SMASK[i] = (uint16)(0x07FF);
				break;
			case 2:
				SSIZE[i] = (int16)(4096);
				SMASK[i] = (uint16)(0x0FFF);
				break;
			case 3:
				SSIZE[i] = (int16)(8192);
				SMASK[i] = (uint16)(0x1FFF);
				break;
			}
		}
		if (rsum < 8192)
		{
			switch((rx_size >> i*2) & 0x03)		/* Set maximum Rx memory size */
			{
			case 0:
				RSIZE[i] = (int16)(1024);
				RMASK[i] = (uint32)(0x000003FF);
				break;
			case 1:
				RSIZE[i] = (int16)(2048);
				RMASK[i] = (uint32)(0x000007FF);
				break;
			case 2:
				RSIZE[i] = (int16)(4096);
				RMASK[i] = (uint32)(0x00000FFF);
				break;
			case 3:
				RSIZE[i] = (int16)(8192);
				RMASK[i] = (uint32)(0x00001FFF);
				break;
			}
		}
		ssum += SSIZE[i];
		rsum += RSIZE[i];

		if (i != 0)					/* Sets base address of Tx and Rx memory for channel #1,#2,#3 */
		{
			SBUFBASEADDRESS[i] = SBUFBASEADDRESS[i-1] + SSIZE[i-1];
			RBUFBASEADDRESS[i] = RBUFBASEADDRESS[i-1] + RSIZE[i-1];
		}
#ifdef __DEF_IINCHIP_DBG__
		printf("%d : %.4x : %.4x : %.4x : %.4x\r\n", i, (uint16)SBUFBASEADDRESS[i], (uint16)RBUFBASEADDRESS[i], SSIZE[i], RSIZE[i]);
#endif
	}

   // for updating gw arp cache
	getGWMAC_processing();

	is_gw_samenet = issubnet_gw();
#ifdef __DEF_IINCHIP_DBG__
   printf("subnet defect : is_gw_samenet is %d\r\n", is_gw_samenet);
#endif
}

/**
 * \brief Sets up Gateway IP address
 * This function sets up gateway IP address.
 * \param addr A pointer to a 4-byte array that will be filled in with
 * the Gateway IP address.
 */
void setgateway(uint8 * addr)
{
	GW_IP[0] = addr[0];
	GW_IP[1] = addr[1];
	GW_IP[2] = addr[2];
	GW_IP[3] = addr[3];
	IINCHIP_WRITE((GATEWAY_PTR + 0),addr[0]);
	IINCHIP_WRITE((GATEWAY_PTR + 1),addr[1]);
	IINCHIP_WRITE((GATEWAY_PTR + 2),addr[2]);
	IINCHIP_WRITE((GATEWAY_PTR + 3),addr[3]);
}
void getGWIP(uint8 * addr)
{
	addr[0] = GW_IP[0];
	addr[1] = GW_IP[1];
	addr[2] = GW_IP[2];
	addr[3] = GW_IP[3];
}
void getGWMAC(uint8 * addr)
{
	addr[0] = GW_MAC[0];
	addr[1] = GW_MAC[1];
	addr[2] = GW_MAC[2];
	addr[3] = GW_MAC[3];
	addr[4] = GW_MAC[4];
	addr[5] = GW_MAC[5];
}

void getGWMAC_processing(void)
{
   uint8 i = 0;
   uint8 j = 0;
	do
	{
   	IINCHIP_WRITE(OPT_PROTOCOL(3),SOCK_STREAM);
   	IINCHIP_WRITE(COMMAND(3),CSOCKINIT);
   	IINCHIP_WRITE(DST_IP_PTR(3),L_IP[0]+1);
   	IINCHIP_WRITE(COMMAND(3),CCONNECT);
   	wait_10ms(10);
   	for (i = 0; i < 6; i++)	GW_MAC[i] = IINCHIP_READ(DST_HA_PTR(3)+i);
   	IINCHIP_WRITE(COMMAND(3),CCLOSE);
   	IINCHIP_WRITE(DST_IP_PTR(3),0x00);

#ifdef __DEF_IINCHIP_DBG__
   	printf("GW_MAC : ");
   	for (i = 0; i < 5; i++)	printf("%.2X.", IINCHIP_READ(DST_HA_PTR(3)+i));
   	printf("%.2X", IINCHIP_READ(DST_HA_PTR(3)+i));
   	printf("\r\n");
#endif

   } while ((IINCHIP_READ(DST_HA_PTR(3)) == 0xff) && j++ <3);
}
/**
 * \brief Sets up subnet mask
 * This function sets subnet mask.
 * \param addr A pointer to a 4-byte array that will be filled in with
 * the subnet mask.
 */
void setsubmask(uint8 * addr)
{
	SUBNET[0] = addr[0];
	SUBNET[1] = addr[1];
	SUBNET[2] = addr[2];
	SUBNET[3] = addr[3];
	IINCHIP_WRITE((SUBNET_MASK_PTR + 0),addr[0]);
	IINCHIP_WRITE((SUBNET_MASK_PTR + 1),addr[1]);
	IINCHIP_WRITE((SUBNET_MASK_PTR + 2),addr[2]);
	IINCHIP_WRITE((SUBNET_MASK_PTR + 3),addr[3]);
}
/*
* return 
* 0 => different subnet
* 1 => same subnet
*/
uint8 issubnet(uint8 *addr)
{
// modify 2005.11.03 
   if (
      (   ((addr[0] & SUBNET[0]) == (L_IP[0] & SUBNET[0]))
          && ((addr[1] & SUBNET[1]) == (L_IP[1] & SUBNET[1]))
          && ((addr[2] & SUBNET[2]) == (L_IP[2] & SUBNET[2]))
          && ((addr[3] & SUBNET[3]) == (L_IP[3] & SUBNET[3]))
      ) ||
      ( (addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF) )
   )
   return 1;
   else return 0;
}

// 2005.10.25 added fix subnet check error
/*
* return 
* 0 => different subnet
* 1 => same subnet
*/
uint8 issubnet_gw(void)
{
   if (   ((L_IP[0] & SUBNET[0]) == (GW_IP[0] & SUBNET[0]))
       && ((L_IP[1] & SUBNET[1]) == (GW_IP[1] & SUBNET[1]))
       && ((L_IP[2] & SUBNET[2]) == (GW_IP[2] & SUBNET[2]))
       && ((L_IP[3] & SUBNET[3]) == (GW_IP[3] & SUBNET[3]))
   ) return 1;
   else return 0;
}
/**
 * \brief Sets up source MAC address
 * This function sets up the source MAC Address.
 * \param addr A pointer to a 6-byte array that will be filled in with
 * the host MAC address.
 */
void setMACAddr(uint8 * addr)
{
	IINCHIP_WRITE((SRC_HA_PTR + 0),addr[0]);
	IINCHIP_WRITE((SRC_HA_PTR + 1),addr[1]);
	IINCHIP_WRITE((SRC_HA_PTR + 2),addr[2]);
	IINCHIP_WRITE((SRC_HA_PTR + 3),addr[3]);
	IINCHIP_WRITE((SRC_HA_PTR + 4),addr[4]);
	IINCHIP_WRITE((SRC_HA_PTR + 5),addr[5]);
}
/**
 * \brief Sets up source IP address
 * This function sets up the source IP Address
 * \param addr A pointer to a 4-byte array that will be filled in with
 * the host IP address.
 */
void setIP(uint8 * addr)
{
	L_IP[0] = addr[0];
	L_IP[1] = addr[1];
	L_IP[2] = addr[2];
	L_IP[3] = addr[3];
	IINCHIP_WRITE((SRC_IP_PTR + 0),addr[0]);
	IINCHIP_WRITE((SRC_IP_PTR + 1),addr[1]);
	IINCHIP_WRITE((SRC_IP_PTR + 2),addr[2]);
	IINCHIP_WRITE((SRC_IP_PTR + 3),addr[3]);

}
/**
 * \brief Set timeout value
 * This function sets up the TCP timeout. \n
 * Timeout Interrupt occurs if the number of retransmission exceed the limit \n
 * when establishing connection and data transmission. 
 * \param timeout timeout values
 */
void setTimeout(uint16 timeout)
{
	IINCHIP_WRITE(TIMEOUT_PTR,(uint8)((timeout & 0xff00) >> 8));
	IINCHIP_WRITE((TIMEOUT_PTR + 1),(uint8)(timeout & 0x00ff));
}
/**
 * \brief Set retry count value
 * This function sets up the TCP retry count.
 * \param retry retry count values
 */
void setRCR(uint8 retry)
{
	IINCHIP_WRITE(RCR,retry);
}
/**
 * \brief Set interrupt mask
 * This function sets up the interrupt mask Enable/Disable appropriate Interrupt.
 * \param mask mask value to setup ('1' : interrupt enable)
 */
void setINTMask(uint8 mask)
{
	IINCHIP_WRITE(INTMASK,mask); // must be setted 0x10.
}
/**
 * \brief Get destination IP address
 * This function returns the destination IP of the socket.
 * \param ch channel
 * \param addr A pointer to store destination IP
 */
void getLocalAddr(uint8 * addr)
{
	addr[0] = IINCHIP_READ(SRC_IP_PTR);
	addr[1] = IINCHIP_READ(SRC_IP_PTR+1);
	addr[2] = IINCHIP_READ(SRC_IP_PTR+2);
	addr[3] = IINCHIP_READ(SRC_IP_PTR+3);
}
void getDestMAC(SOCKET s, uint8 * addr)
{
	addr[0] = IINCHIP_READ(DST_HA_PTR(s));
	addr[1] = IINCHIP_READ(DST_HA_PTR(s)+1);
	addr[2] = IINCHIP_READ(DST_HA_PTR(s)+2);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -