📄 w5100.c
字号:
/*
u8 getSn_IR(u8 s)
{
return IINCHIP_READ(Sn_IR(s));
}
*/
/**
@brief get socket status
*/
u8 getSn_SR(u8 s)
{
return IINCHIP_READ(Sn_SR(s));
}
/**
@brief get socket TX free buf size
This gives free buffer size of transmit buffer. This is the data size that user can transmit.
User shuold check this value first and control the size of transmitting data
*/
u16 getSn_TX_FSR(u8 s)
{
u16 val=0,val1=0;
do
{
val1 = IINCHIP_READ(Sn_TX_FSR0(s));
val1 = (val1 << 8) + IINCHIP_READ(Sn_TX_FSR0(s) + 1);
if (val1 != 0)
{
val = IINCHIP_READ(Sn_TX_FSR0(s));
val = (val << 8) + IINCHIP_READ(Sn_TX_FSR0(s) + 1);
}
} while (val != val1);
return val;
}
/**
@brief get socket RX recv buf size
This gives size of received data in receive buffer.
*/
u16 getSn_RX_RSR(u8 s)
{
u16 val=0,val1=0;
do
{
val1 = IINCHIP_READ(Sn_RX_RSR0(s));
val1 = (val1 << 8) + IINCHIP_READ(Sn_RX_RSR0(s) + 1);
if(val1 != 0)
{
val = IINCHIP_READ(Sn_RX_RSR0(s));
val = (val << 8) + IINCHIP_READ(Sn_RX_RSR0(s) + 1);
}
} while (val != val1);
return val;
}
/**
@brief This function is being called by send() and sendto() function also.
This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
register. User should read upper byte first and lower byte later to get proper value.
*/
void send_data_processing(u8 s, u8 *data, u16 len)
{
u16 ptr;
ptr = IINCHIP_READ(Sn_TX_WR0(s));
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_TX_WR0(s) + 1);
write_data(s, data, (u8 *)(ptr), len);
ptr += len;
IINCHIP_WRITE(Sn_TX_WR0(s),(u8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_TX_WR0(s) + 1),(u8)(ptr & 0x00ff));
}
/**
@brief This function is being called by recv() also.
This function read the Rx read pointer register
and after copy the data from receive buffer update the Rx write pointer register.
User should read upper byte first and lower byte later to get proper value.
*/
void recv_data_processing(u8 s, u8 *data, u16 len)
{
u16 ptr;
ptr = IINCHIP_READ(Sn_RX_RD0(s));
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);
#ifdef __DEF_IINCHIP_DBG__
printf("ISR_RX: rd_ptr : %.4x\r\n", ptr);
#endif
read_data(s, (u8 *)ptr, data, len); // read data
ptr += len;
IINCHIP_WRITE(Sn_RX_RD0(s),(u8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(u8)(ptr & 0x00ff));
}
/**
@brief for copy the data form application buffer to Transmite buffer of the chip.
This function is being used for copy the data form application buffer to Transmite
buffer of the chip. It calculate the actual physical address where one has to write
the data in transmite buffer. Here also take care of the condition while it exceed
the Tx memory uper-bound of socket.
*/
void write_data(u8 s, vu8 * src, vu8 * dst, u16 len)
{
u16 size;
u16 dst_mask;
u8 * dst_ptr;
dst_mask = (u16)dst & getIINCHIP_TxMASK(s);
dst_ptr = (u8 *)(getIINCHIP_TxBASE(s) + dst_mask);
if (dst_mask + len > getIINCHIP_TxMAX(s))
{
size = getIINCHIP_TxMAX(s) - dst_mask;
wiz_write_buf((u32)dst_ptr, (u8*)src, size);
src += size;
size = len - size;
dst_ptr = (u8 *)(getIINCHIP_TxBASE(s));
wiz_write_buf((u32)dst_ptr, (u8*)src, size);
}
else
{
wiz_write_buf((u32)dst_ptr, (u8*)src, len);
}
}
/**
@brief This function is being used for copy the data form Receive buffer of the chip to application buffer.
It calculate the actual physical address where one has to read
the data from Receive buffer. Here also take care of the condition while it exceed
the Rx memory uper-bound of socket.
*/
void read_data(u8 s, vu8 * src, vu8 * dst, u16 len)
{
u16 size;
u16 src_mask;
u8 * src_ptr;
src_mask = (u16)src & getIINCHIP_RxMASK(s);
src_ptr = (u8 *)(getIINCHIP_RxBASE(s) + src_mask);
if( (src_mask + len) > getIINCHIP_RxMAX(s) )
{
size = getIINCHIP_RxMAX(s) - src_mask;
wiz_read_buf((u32)src_ptr, (u8*)dst,size);
dst += size;
size = len - size;
src_ptr = (u8 *)(getIINCHIP_RxBASE(s));
wiz_read_buf((u32)src_ptr, (u8*) dst,size);
}
else
{
wiz_read_buf((u32)src_ptr, (u8*) dst,len);
}
}
#ifdef __DEF_IINCHIP_PPP__
#define PPP_OPTION_BUF_LEN 64
u8 pppinit_in(u8 * id, u8 idlen, u8 * passwd, u8 passwdlen);
/**
@brief make PPPoE connection
@return 1 => success to connect, 2 => Auth fail, 3 => timeout, 4 => Auth type not support
*/
u8 pppinit(u8 * id, u8 idlen, u8 * passwd, u8 passwdlen)
{
u8 ret;
u8 isr;
// PHASE0. W5100 PPPoE(ADSL) setup
// enable pppoe mode
printf("-- PHASE 0. W5100 PPPoE(ADSL) setup process --\r\n");
printf("\r\n");
IINCHIP_WRITE(MR,IINCHIP_READ(MR) | MR_PPPOE);
// open socket in pppoe mode
isr = IINCHIP_READ(Sn_IR(0));// first clear isr(0), W5100 at present time
IINCHIP_WRITE(Sn_IR(0),isr);
IINCHIP_WRITE(PTIMER,200); // 5sec timeout
IINCHIP_WRITE(PMAGIC,0x01); // magic number
IINCHIP_WRITE(Sn_MR(0),Sn_MR_PPPOE);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_OPEN);
ret = pppinit_in(id, idlen, passwd, passwdlen);
// close ppp connection socket
IINCHIP_WRITE(Sn_CR(0),Sn_CR_CLOSE);
return ret;
}
u8 pppinit_in(u8 * id, u8 idlen, u8 * passwd, u8 passwdlen)
{
u8 loop_idx = 0;
u8 isr = 0;
u8 buf[PPP_OPTION_BUF_LEN];
u16 len;
u8 str[PPP_OPTION_BUF_LEN];
u8 str_idx,dst_idx;
// PHASE1. PPPoE Discovery
// start to connect pppoe connection
printf("-- PHASE 1. PPPoE Discovery process --");
printf(" ok\r\n");
printf("\r\n");
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCON);
wait_10ms(100);
loop_idx = 0;
//check whether PPPoE discovery end or not
while (!(IINCHIP_READ(Sn_IR(0)) & Sn_IR_PNEXT))
{
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout before LCP\r\n");
return 3;
}
wait_10ms(100);
}
// PHASE2. LCP process
printf("-- PHASE 2. LCP process --");
// send LCP Request
{
// Magic number option
// option format (type value + length value + data)
// write magic number value
buf[0] = 0x05; // type value
buf[1] = 0x06; // length value
buf[2] = 0x01; buf[3] = 0x01; buf[4] = 0x01; buf[5]= 0x01; // data
// for MRU option, 1492 0x05d4
// buf[6] = 0x01; buf[7] = 0x04; buf[8] = 0x05; buf[9] = 0xD4;
}
send_data_processing(0, buf, 0x06);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR); // send request
wait_10ms(100);
while (!((isr = IINCHIP_READ(Sn_IR(0))) & Sn_IR_PNEXT))
{
if (isr & Sn_IR_PRECV) // Not support option
{
len = getSn_RX_RSR(0);
if ( len > 0 )
{
recv_data_processing(0, str, len);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_RECV);
// for debug
//printf("LCP proc\r\n"); for (i = 0; i < len; i++) printf ("%02x ", str[i]); printf("\r\n");
// get option length
len = str[4]; len = ((len & 0x00ff) << 8) + str[5];
len += 2;
str_idx = 6; dst_idx = 0; // ppp header is 6 byte, so starts at 6.
do
{
if ((str[str_idx] == 0x01) || (str[str_idx] == 0x02) || (str[str_idx] == 0x03) || (str[str_idx] == 0x05))
{
// skip as length of support option. str_idx+1 is option's length.
str_idx += str[str_idx+1];
}
else
{
// not support option , REJECT
memcpy((u8 *)(buf+dst_idx), (u8 *)(str+str_idx), str[str_idx+1]);
dst_idx += str[str_idx+1]; str_idx += str[str_idx+1];
}
} while (str_idx != len);
// for debug
// printf("LCP dst proc\r\n"); for (i = 0; i < dst_idx; i++) printf ("%02x ", dst[i]); printf("\r\n");
// send LCP REJECT packet
send_data_processing(0, buf, dst_idx);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCJ);
}
}
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout after LCP\r\n");
return 3;
}
wait_10ms(100);
}
printf(" ok\r\n");
printf("\r\n");
printf("-- PHASE 3. PPPoE(ADSL) Authentication mode --\r\n");
printf("Authentication protocol : %.2x %.2x, ", IINCHIP_READ(PATR0), IINCHIP_READ(PATR0+1));
loop_idx = 0;
if (IINCHIP_READ(PATR0) == 0xc0 && IINCHIP_READ(PATR0+1) == 0x23)
{
printf("PAP\r\n"); // in case of adsl normally supports PAP.
// send authentication data
// copy (idlen + id + passwdlen + passwd)
buf[loop_idx] = idlen; loop_idx++;
memcpy((u8 *)(buf+loop_idx), (u8 *)(id), idlen); loop_idx += idlen;
buf[loop_idx] = passwdlen; loop_idx++;
memcpy((u8 *)(buf+loop_idx), (u8 *)(passwd), passwdlen); loop_idx += passwdlen;
send_data_processing(0, buf, loop_idx);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR);
wait_10ms(100);
}
else if (IINCHIP_READ(PATR0) == 0xc2 && IINCHIP_READ(PATR0+1) == 0x23)
{
u8 chal_len;
md5_ctx context;
u8 digest[16];
len = getSn_RX_RSR(0);
if ( len > 0 )
{
recv_data_processing(0, str, len);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_RECV);
#ifdef __DEF_IINCHIP_DBG__
printf("recv CHAP\r\n");
{
s16 i;
for (i = 0; i < 32; i++)
printf ("%02x ", str[i]);
}
printf("\r\n");
#endif
// str is C2 23 xx CHAL_ID xx xx CHAP_LEN CHAP_DATA
// index 0 1 2 3 4 5 6 7 ...
memset(buf,0x00,64);
buf[loop_idx] = str[3]; loop_idx++; // chal_id
memcpy((u8 *)(buf+loop_idx), (u8 *)(passwd), passwdlen); loop_idx += passwdlen; //passwd
chal_len = str[6]; // chal_id
memcpy((u8 *)(buf+loop_idx), (u8 *)(str+7), chal_len); loop_idx += chal_len; //challenge
buf[loop_idx] = 0x80;
#ifdef __DEF_IINCHIP_DBG__
printf("CHAP proc d1\r\n");
{
s16 i;
for (i = 0; i < 64; i++)
printf ("%02x ", buf[i]);
}
printf("\r\n");
#endif
md5_init(&context);
md5_update(&context, buf, loop_idx);
md5_final(digest, &context);
#ifdef __DEF_IINCHIP_DBG__
printf("CHAP proc d1\r\n");
{
s16 i;
for (i = 0; i < 16; i++)
printf ("%02x", digest[i]);
}
printf("\r\n");
#endif
loop_idx = 0;
buf[loop_idx] = 16; loop_idx++; // hash_len
memcpy((u8 *)(buf+loop_idx), (u8 *)(digest), 16); loop_idx += 16; // hashed value
memcpy((u8 *)(buf+loop_idx), (u8 *)(id), idlen); loop_idx += idlen; // id
send_data_processing(0, buf, loop_idx);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR);
wait_10ms(100);
}
}
else
{
printf("Not support\r\n");
#ifdef __DEF_IINCHIP_DBG__
printf("Not support PPP Auth type: %.2x%.2x\r\n",IINCHIP_READ(PATR0), IINCHIP_READ(PATR0+1));
#endif
return 4;
}
printf("\r\n");
printf("-- Waiting for PPPoE server's admission --");
loop_idx = 0;
while (!((isr = IINCHIP_READ(Sn_IR(0))) & Sn_IR_PNEXT))
{
if (isr & Sn_IR_PFAIL)
{
printf("failed\r\nReinput id, password..\r\n");
return 2;
}
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout after PAP\r\n");
return 3;
}
wait_10ms(100);
}
printf("ok\r\n");
printf("\r\n");
printf("-- PHASE 4. IPCP process --");
// IP Address
buf[0] = 0x03; buf[1] = 0x06; buf[2] = 0x00; buf[3] = 0x00; buf[4] = 0x00; buf[5] = 0x00;
send_data_processing(0, buf, 6);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR);
wait_10ms(100);
loop_idx = 0;
while (1)
{
if (IINCHIP_READ(Sn_IR(0)) & Sn_IR_PRECV)
{
len = getSn_RX_RSR(0);
if ( len > 0 )
{
recv_data_processing(0, str, len);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_RECV);
//for debug
//printf("IPCP proc\r\n"); for (i = 0; i < len; i++) printf ("%02x ", str[i]); printf("\r\n");
str_idx = 6; dst_idx = 0;
if (str[2] == 0x03) // in case of NAK
{
do
{
if (str[str_idx] == 0x03) // request only ip information
{
memcpy((u8 *)(buf+dst_idx), (u8 *)(str+str_idx), str[str_idx+1]);
dst_idx += str[str_idx+1]; str_idx += str[str_idx+1];
}
else
{
// skip byte
str_idx += str[str_idx+1];
}
// for debug
//printf("s: %d, d: %d, l: %d", str_idx, dst_idx, len);
} while (str_idx != len);
send_data_processing(0, buf, dst_idx);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR); // send ipcp request
wait_10ms(100);
break;
}
}
}
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout after IPCP\r\n");
return 3;
}
wait_10ms(100);
send_data_processing(0, buf, 6);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR); //ipcp re-request
}
loop_idx = 0;
while (!(IINCHIP_READ(Sn_IR(0)) & Sn_IR_PNEXT))
{
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout after IPCP NAK\r\n");
return 3;
}
wait_10ms(100);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR); // send ipcp request
}
printf("ok\r\n");
printf("\r\n");
return 1;
// after this function, User must save the pppoe server's mac address and pppoe session id in current connection
}
/**
@brief terminate PPPoE connection
*/
u8 pppterm(u8 * mac, u8 * sessionid)
{
u16 i;
u8 isr;
#ifdef __DEF_IINCHIP_DBG__
printf("pppterm()\r\n");
#endif
/* Set PPPoE bit in MR(Common Mode Register) : enable socket0 pppoe */
IINCHIP_WRITE(MR,IINCHIP_READ(MR) | MR_PPPOE);
// write pppoe server's mac address and session id
// must be setted these value.
for (i = 0; i < 6; i++) IINCHIP_WRITE((Sn_DHAR0(0)+i),mac[i]);
for (i = 0; i < 2; i++) IINCHIP_WRITE((Sn_DPORT0(0)+i),sessionid[i]);
isr = IINCHIP_READ(Sn_IR(0));
IINCHIP_WRITE(Sn_IR(0),isr);
//open socket in pppoe mode
IINCHIP_WRITE(Sn_MR(0),Sn_MR_PPPOE);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_OPEN);
wait_1us(1);
// close pppoe connection
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PDISCON);
wait_10ms(100);
// close socket
IINCHIP_WRITE(Sn_CR(0),Sn_CR_CLOSE);
#ifdef __DEF_IINCHIP_DBG__
printf("pppterm() end ..\r\n");
#endif
return 1;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -