📄 w3150a.c
字号:
/*
* (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 + -