#include <stdio.h>
#include <string.h>
#include "w5300.h"
#include "md5.h"
static uint8 Subnet[4];
uint32 TXMEM_SIZE[MAX_SOCK_NUM];
uint32 RXMEM_SIZE[MAX_SOCK_NUM];
uint8 SOCK_INT[MAX_SOCK_NUM];
/***********************
* Basic I/O Function *
***********************/
uint8 IINCHIP_READ(uint16 addr)
{
#if (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_DIRECT_MODE__)
return (*((uint8*)addr));
#else
uint8 data;
IINCHIP_CRITICAL_SECTION_ENTER();
*((uint8*)IDM_AR0) = (uint8)(addr >> 8);
*((uint8*)IDM_AR1) = (uint8)(addr & 0x00ff);
if(addr & 0x01) data = *((uint8*)IDM_DR1);
else data = *((uint8*)IDM_DR0);
IINCHIP_CRITICAL_SECTION_EXIT();
return data;
#endif
}
void IINCHIP_WRITE(uint16 addr, uint8 data)
{
#if (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_DIRECT_MODE__)
(*((vuint8*)addr)) = data;
#else
IINCHIP_CRITICAL_SECTION_ENTER();
*((vuint8*)IDM_AR0) = (uint8)(addr >> 8);
*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00ff);
if(addr & 0x01) *((vuint8*)IDM_DR1) = data;
else *((vuint8*)IDM_DR0) = data;
IINCHIP_CRITICAL_SECTION_EXIT();
#endif
}
uint16 getMR(void)
{
uint16 ret;
ret = *(uint8*)MR0;
ret = (ret << 8) + *(uint8*)MR1;
return ret;
}
void setMR(uint16 val)
{
*(uint8*)MR0 = (uint8)((val >> 8) & 0xff);
*(uint8*)MR1 = (uint8)(val & 0xff);
}
/***********************************
* COMMON Register Access Function *
***********************************/
/* Interrupt */
uint16 getIR(void)
{
uint16 ret;
ret = IINCHIP_READ(IR0);
ret = (ret << 8) + (IINCHIP_READ(IR1));
return ret;
}
void setIR(uint16 val)
{
IINCHIP_WRITE(IR0, (uint8)(val >> 8));
IINCHIP_WRITE(IR1, (uint8)(val & 0xff));
}
uint16 getIMR(void)
{
uint16 ret;
ret = IINCHIP_READ(IMR0);
ret = (ret<<8) + IINCHIP_READ(IMR1);
return ret;
}
void setIMR(uint16 mask)
{
IINCHIP_WRITE(IMR0, (uint8)(mask >> 8));
IINCHIP_WRITE(IMR1, (uint8)(mask & 0xff));
}
/* Network Information */
void getSHAR(uint8 * addr)
{
addr[0] = (uint8)IINCHIP_READ(SHAR0);
addr[1] = (uint8)IINCHIP_READ(SHAR1);
addr[2] = (uint8)IINCHIP_READ(SHAR2);
addr[3] = (uint8)IINCHIP_READ(SHAR3);
addr[4] = (uint8)IINCHIP_READ(SHAR4);
addr[5] = (uint8)IINCHIP_READ(SHAR5);
}
void setSHAR(uint8 * addr)
{
IINCHIP_WRITE(SHAR0,(uint8)addr[0]);
IINCHIP_WRITE(SHAR1,(uint8)addr[1]);
IINCHIP_WRITE(SHAR2,(uint8)addr[2]);
IINCHIP_WRITE(SHAR3,(uint8)addr[3]);
IINCHIP_WRITE(SHAR4,(uint8)addr[4]);
IINCHIP_WRITE(SHAR5,(uint8)addr[5]);
}
void getGAR(uint8 * addr)
{
addr[0] = (uint8)(IINCHIP_READ(GAR0));
addr[1] = (uint8)(IINCHIP_READ(GAR1));
addr[2] = (uint8)(IINCHIP_READ(GAR2));
addr[3] = (uint8)(IINCHIP_READ(GAR3));
}
void setGAR(uint8 * addr)
{
IINCHIP_WRITE(GAR0, (uint8)addr[0]);
IINCHIP_WRITE(GAR1, (uint8)addr[1]);
IINCHIP_WRITE(GAR2, (uint8)addr[2]);
IINCHIP_WRITE(GAR3, (uint8)addr[3]);
}
void getSUBR(uint8 * addr)
{
addr[0] = (uint8)Subnet[0];
addr[1] = (uint8)Subnet[1];
addr[2] = (uint8)Subnet[2];
addr[3] = (uint8)Subnet[3];
}
void setSUBR(uint8 * addr)
{
Subnet[0] = addr[0];
Subnet[1] = addr[1];
Subnet[2] = addr[2];
Subnet[3] = addr[3];
}
void ApplySubnet()
{
IINCHIP_WRITE((SUBR),Subnet[0]);
IINCHIP_WRITE((SUBR),Subnet[1]);
IINCHIP_WRITE((SUBR),Subnet[2]);
IINCHIP_WRITE((SUBR),Subnet[3]);
}
void ClearSubnet()
{
IINCHIP_WRITE((SUBR),0);
IINCHIP_WRITE((SUBR),0);
IINCHIP_WRITE((SUBR),0);
IINCHIP_WRITE((SUBR),0);
}
void getSIPR(uint8 * addr)
{
addr[0] = (uint8)(IINCHIP_READ(SIPR0));
addr[1] = (uint8)(IINCHIP_READ(SIPR1));
addr[2] = (uint8)(IINCHIP_READ(SIPR2));
addr[3] = (uint8)(IINCHIP_READ(SIPR3));
}
void setSIPR(uint8 * addr)
{
IINCHIP_WRITE(SIPR0,(uint8)addr[0]);
IINCHIP_WRITE(SIPR1,(uint8)addr[1]);
IINCHIP_WRITE(SIPR2,(uint8)addr[2]);
IINCHIP_WRITE(SIPR3,(uint8)addr[3]);
}
/* Retransmittion */
uint16 getRTR(void)
{
uint16 ret;
ret = IINCHIP_READ(RTR0);
ret = (RTR0 << 8) + IINCHIP_READ(RTR1);
return ret;
}
void setRTR(uint16 timeout)
{
IINCHIP_WRITE(RTR0, ((uint8)(timeout >> 8)));
IINCHIP_WRITE(RTR1, timeout & 0xff);
}
uint8 getRCR(void)
{
return (uint8)IINCHIP_READ(RCR1);
}
void setRCR(uint8 retry)
{
IINCHIP_WRITE(RCR1,retry);
}
/* PPPoE */
uint16 getPATR(void)
{
uint16 ret;
ret = IINCHIP_READ(PATR0);
ret = (ret << 8) + IINCHIP_READ(PATR1);
return ret;
}
uint8 getPTIMER(void)
{
return (uint8)IINCHIP_READ(PTIMER1);
}
void setPTIMER
(uint8 time)
{
IINCHIP_WRITE
(PTIMER1
,time);
}
uint8 getPMAGICR(void)
{
return (uint8)IINCHIP_READ(PMAGICR1);
}
void setPMAGICR(uint8 magic)
{
IINCHIP_WRITE(PMAGICR1,magic);
}
uint16 getPSIDR(void)
{
uint16 ret;
ret = IINCHIP_READ(PSIDR0);
ret = (ret << 8) + IINCHIP_READ(PSIDR1);
return ret;
}
void getPDHAR(uint8* addr)
{
addr[0] = (uint8)(IINCHIP_READ(PDHAR0));
addr[1] = (uint8)(IINCHIP_READ(PDHAR1));
addr[2] = (uint8)(IINCHIP_READ(PDHAR2));
addr[3] = (uint8)(IINCHIP_READ(PDHAR3));
addr[4] = (uint8)(IINCHIP_READ(PDHAR4));
addr[5] = (uint8)(IINCHIP_READ(PDHAR5));
}
/* ICMP packets */
void getUIPR(uint8* addr)
{
addr[0] = (uint8)(IINCHIP_READ(UIPR0));
addr[1] = (uint8)(IINCHIP_READ(UIPR1));
addr[2] = (uint8)(IINCHIP_READ(UIPR2));
addr[3] = (uint8)(IINCHIP_READ(UIPR3));
}
uint16 getUPORTR(void)
{
uint16 ret;
ret = IINCHIP_READ(UPORTR0);
ret = (ret << 8) + IINCHIP_READ(UPORTR1);
return ret;
}
uint16 getFMTUR(void)
{
uint16 ret;
ret = IINCHIP_READ(FMTUR0);
ret = (ret << 8) + IINCHIP_READ(FMTUR1);
return ret;
}
/* PIN "BRYDn" */
uint8 getPn_BRDYR(uint8 p)
{
return (uint8)IINCHIP_READ(Pn_BRDYR1(p));
}
void setPn_BRDYR(uint8 p, uint8 cfg)
{
IINCHIP_WRITE(Pn_BRDYR1(p),cfg);
}
uint16 getPn_BDPTHR(uint8 p)
{
uint16 ret;
ret = IINCHIP_READ(Pn_BDPTHR0(p));
ret = (ret << 8) + IINCHIP_READ(Pn_BDPTHR1(p));
return ret;
}
void setPn_BDPTHR(uint8 p, uint16 depth)
{
IINCHIP_WRITE(Pn_BDPTHR0(p), (uint8)(depth >> 8));
IINCHIP_WRITE(Pn_BDPTHR1(p), (uint8)(depth & 0xff));
}
/* IINCHIP ID */
uint16 getIDR(void)
{
uint16 ret;
ret = IINCHIP_READ(IDR0);
ret = (ret << 8) + IINCHIP_READ(IDR1);
return ret;
}
/***********************************
* SOCKET Register Access Function *
***********************************/
/* SOCKET control */
uint16 getSn_MR(SOCKET s)
{
uint16 ret;
ret = IINCHIP_READ(Sn_MR0(s));
ret = (ret << 8) + IINCHIP_READ(Sn_MR1(s));
return ret;
}
void setSn_MR(SOCKET s, uint16 mode)
{
IINCHIP_WRITE(Sn_MR0(s), (uint8)(mode >> 8));
IINCHIP_WRITE(Sn_MR1(s), (uint8)(mode & 0xff));
}
uint8 getSn_CR(SOCKET s)
{
return IINCHIP_READ(Sn_CR1(s));
}
void setSn_CR(SOCKET s, uint8 com)
{
IINCHIP_WRITE(Sn_CR1(s), (uint8)(com & 0xff));
while(IINCHIP_READ(Sn_CR1(s))); // wait until Sn_CR is cleared.
}
uint8 getSn_IMR(SOCKET s)
{
return (uint8)IINCHIP_READ(Sn_IMR1(s));
}
void setSn_IMR(SOCKET s, uint8 mask)
{
IINCHIP_WRITE(Sn_IMR1(s),mask);
}
uint8 getSn_IR(SOCKET s)
{
#ifdef __DEF_IINCHIP_INT__ // In case of using ISR routine of iinchip
return SOCK_INT[s];
#else // In case of processing directly
return (uint8)IINCHIP_READ(Sn_IR1(s));
#endif
}
void setSn_IR(SOCKET s, uint8 ir)
{
#ifdef __DEF_IINCHIP_INT__ // In case of using ISR routine of iinchip
SOCK_INT[s] = SOCK_INT[s] & ~(ir);
#else // In case of processing directly
IINCHIP_WRITE(Sn_IR1(s),ir);
#endif
}
/* SOCKET information */
uint8 getSn_SSR(SOCKET s)
{
uint8 ssr, ssr1;
ssr = (uint8)IINCHIP_READ(Sn_SSR1(s)); // first read
while(1)
{
ssr1 = (uint8)IINCHIP_READ(Sn_SSR1(s)); // second read
if(ssr == ssr1) break; // if first == sencond, Sn_SSR value is valid.
ssr = ssr1; // if first <> second, save second value into first.
}
return ssr;
}
void getSn_DHAR(SOCKET s, uint8* addr)
{
addr[0] = (uint8)(IINCHIP_READ(Sn_DHAR0(s)));
addr[1] = (uint8)(IINCHIP_READ(Sn_DHAR1(s)));
addr[2] = (uint8)(IINCHIP_READ(Sn_DHAR2(s)));
addr[3] = (uint8)(IINCHIP_READ(Sn_DHAR3(s)));
addr[4] = (uint8)(IINCHIP_READ(Sn_DHAR4(s)));
addr[5] = (uint8)(IINCHIP_READ(Sn_DHAR5(s)));
}
void setSn_DHAR(SOCKET s, uint8* addr)
{
IINCHIP_WRITE(Sn_DHAR0(s), (uint8)(addr[0]));
IINCHIP_WRITE(Sn_DHAR1(s), (uint8)(addr[1]));
IINCHIP_WRITE(Sn_DHAR2(s), (uint8)(addr[2]));
IINCHIP_WRITE(Sn_DHAR3(s), (uint8)(addr[3]));
IINCHIP_WRITE(Sn_DHAR4(s), (uint8)(addr[4]));
IINCHIP_WRITE(Sn_DHAR5(s), (uint8)(addr[5]));
}
// M_15052008 : Delete this function
//uint16 getSn_DPORTR(SOCKET s)
//{
// return IINCHIP_READ(Sn_DPORTR(s));
//}
void setSn_DPORTR(SOCKET s, uint16 port)
{
IINCHIP_WRITE(Sn_DPORTR0(s), (uint8)(port >>8));
IINCHIP_WRITE(Sn_DPORTR1(s), (uint8)(port & 0xff));
}
void getSn_DIPR(SOCKET s, uint8* addr)
{
addr[0] = (uint8)(IINCHIP_READ(Sn_DIPR0(s)));
addr[1] = (uint8)(IINCHIP_READ(Sn_DIPR1(s)));
addr[2] = (uint8)(IINCHIP_READ(Sn_DIPR2(s)));
addr[3] = (uint8)(IINCHIP_READ(Sn_DIPR3(s)));
}
void setSn_DIPR(SOCKET s, uint8* addr)
{
IINCHIP_WRITE(Sn_DIPR0(s), (uint8)addr[0]);
IINCHIP_WRITE(Sn_DIPR1(s), (uint8)addr[1]);
IINCHIP_WRITE(Sn_DIPR2(s), (uint8)addr[2]);
IINCHIP_WRITE(Sn_DIPR3(s), (uint8)addr[3]);
}
uint16 getSn_MSSR(SOCKET s)
{
uint16 ret;
ret = IINCHIP_READ(Sn_MSSR0(s));
ret = (ret << 8) + IINCHIP_READ(Sn_MSSR1(s));
return ret;
}
void setSn_MSSR(SOCKET s, uint16 mss)
{
IINCHIP_WRITE(Sn_MSSR0(s), (uint8)(mss >> 8));
IINCHIP_WRITE(Sn_MSSR1(s), (uint8)(mss & 0xff));
}
/* SOCKET communication */
uint8 getSn_KPALVTR(SOCKET s)
{
return IINCHIP_READ(Sn_KPALVTR(s));
}
void setSn_KPALVTR
(SOCKET s
, uint8 time)
{
IINCHIP_WRITE
(Sn_KPALVTR
(s
), time);
}
uint32 getSn_TX_WRSR(SOCKET s)
{
uint32 ret;
ret = IINCHIP_READ(Sn_TX_WRSR0(s));
ret = (ret << 8) + IINCHIP_READ(Sn_TX_WRSR1(s));
ret = (ret << 8) + IINCHIP_READ(Sn_TX_WRSR2(s));
ret = (ret << 8) + IINCHIP_READ(Sn_TX_WRSR3(s));
return ret;
}
void setSn_TX_WRSR(SOCKET s, uint32 size)
{
IINCHIP_WRITE(Sn_TX_WRSR0(s), (uint8)(size >> 24));
IINCHIP_WRITE(Sn_TX_WRSR1(s), (uint8)(size >> 16));
IINCHIP_WRITE(Sn_TX_WRSR2(s), (uint8)(size >> 8));
IINCHIP_WRITE(Sn_TX_WRSR3(s), (uint8)(size & 0xff));
}
uint32 getSn_TX_FSR(SOCKET s)
{
uint32 free_tx_size=0;
uint32 free_tx_size1=0;
while(1)
{
free_tx_size = IINCHIP_READ(Sn_TX_FSR0(s)); // read
free_tx_size = (free_tx_size << 8) + IINCHIP_READ(Sn_TX_FSR1(s));
free_tx_size = (free_tx_size << 8) + IINCHIP_READ(Sn_TX_FSR2(s));
free_tx_size = (free_tx_size << 8) + IINCHIP_READ(Sn_TX_FSR3(s));
if(free_tx_size == free_tx_size1) break; // if first == sencond, Sn_TX_FSR value is valid.
free_tx_size1 = free_tx_size; // save second value into first
}
return free_tx_size;
}
uint32 getSn_RX_RSR(SOCKET s)
{
uint32 received_rx_size=0;
uint32 received_rx_size1=1;
while(1)
{
received_rx_size = IINCHIP_READ(Sn_RX_RSR0(s));
received_rx_size = (received_rx_size << 8) + IINCHIP_READ(Sn_RX_RSR1(s)); // read
received_rx_size = (received_rx_size << 8) + IINCHIP_READ(Sn_RX_RSR2(s));
received_rx_size = (received_rx_size << 8) + IINCHIP_READ(Sn_RX_RSR3(s));
if(received_rx_size == received_rx_size1) break;
received_rx_size1 = received_rx_size; // if first == sencond, Sn_RX_RSR value is valid.
} // save second value into first
return received_rx_size;
}
void setSn_TX_FIFOR(SOCKET s, uint16 data)
{
IINCHIP_WRITE(Sn_TX_FIFOR0(s), (uint8)(data >> 8));
IINCHIP_WRITE(Sn_TX_FIFOR1(s), (uint8)(data & 0xff));
}
uint16 getSn_RX_FIFOR(SOCKET s)
{
uint16 ret;
ret = IINCHIP_READ(Sn_RX_FIFOR0(s));
ret = (ret << 8) + IINCHIP_READ(Sn_RX_FIFOR1(s));
return ret;
}
/* IP header field */
uint8 getSn_PROTOR(SOCKET s)
{
return (uint8)IINCHIP_READ(Sn_PROTOR(s));
}
void setSn_PROTOR(SOCKET s, uint8 pronum)
{
IINCHIP_WRITE(Sn_PROTOR(s), pronum);
}
uint8 getSn_TOSR(SOCKET s)
{
return (uint8)IINCHIP_READ(Sn_TOSR1(s));
}
void setSn_TOSR(SOCKET s, uint8 tos)
{
IINCHIP_WRITE(Sn_TOSR1(s),tos);
}
uint8 getSn_TTLR(SOCKET s)
{
return (uint8)IINCHIP_READ(Sn_TTLR1(s));
}
void setSn_TTLR(SOCKET s, uint8 ttl)
{
IINCHIP_WRITE(Sn_TTLR1(s),ttl);
}
uint8 getSn_FRAGR(SOCKET s)
{
return (uint8)IINCHIP_READ(Sn_FRAGR1(s));
}
void setSn_FRAGR(SOCKET s, uint8 frag)
{
IINCHIP_WRITE(Sn_FRAGR1(s),frag);
}
/*******
* ETC *
*******/
/* Initialization & Interrupt request routine */
void iinchip_init(void)
{
*((uint8*)MR) = MR_RST;
wait_1ms(5);
#if (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_INDIRECT_MODE__)
*((vint8*)MR) |= MR_IND;
#ifdef __DEF_IINCHIP_DBG__
printf("MR value is %04x\r\n",*((vuint16
*)MR
));
#endif
#endif
}
//This statement is commented for using 'Doxygen'.
//#ifdef __DEF_IINCHIP_INT__
void iinchip_irq(void)
{
uint16 int_val;
uint16 idx;
IINCHIP_CRITICAL_SECTION_ENTER();
// M_01052008 : replaced '==' with '='
//while(int_val == IINCHIP_READ(IR)) // process all interrupt
while((int_val = ((IINCHIP_READ(IR0) << 8) | IINCHIP_READ(IR1)))) // process all interrupt
{
for(idx = 0 ; idx < MAX_SOCK_NUM ; idx++)
{
if (int_val & IR_SnINT(idx)) // check the SOCKETn interrupt
{
SOCK_INT[idx] |= (uint8)IINCHIP_READ(Sn_IR1(idx)); // Save the interrupt stauts to SOCK_INT[idx]
IINCHIP_WRITE(Sn_IR1(idx),SOCK_INT[idx]); // Clear the interrupt status bit of SOCKETn
}
}
if (int_val & (IR_IPCF << 8)) // check the IP conflict interrupt
{
printf("IP conflict : %04x\r\n", int_val
);
}
if (int_val & (IR_DPUR << 8)) // check the unreachable destination interrupt
{
printf("INT Port Unreachable : %04x\r\n", int_val
);
printf("UIPR : %d.%d.%d.%d\r\n", IINCHIP_READ
(UIPR0
),
IINCHIP_READ(UIPR1),
IINCHIP_READ(UIPR2),
IINCHIP_READ(UIPR3));
printf("UPORTR : %02x%02x\r\n", IINCHIP_READ
(UPORTR0
),IINCHIP_READ
(UPORTR1
));
}
IINCHIP_WRITE(IR0, (uint8)(int_val >> 8));
}
IINCHIP_CRITICAL_SECTION_EXIT();
}
//This statement is commented for using 'Doxygen'.
//#endif
/* Internal memory operation */
uint8 sysinit(uint8* tx_size, uint8* rx_size)
{
uint16 i;
uint16 ssum=0,rsum=0;
uint mem_cfg = 0;
for(i=0; i < MAX_SOCK_NUM; i++)
{
if(tx_size[i] > 64)
{
#ifdef __DEF_IINCHIP_DBG__
printf("Illegal Channel(%d) TX Memory Size.\r\n",i
);
#endif
return 0;
}
if(rx_size[i] > 64)
{
#ifdef __DEF_IINCHIP_DBG__
printf("Illegal Channel(%d) RX Memory Size.\r\n",i
);
#endif
return 0;
}
ssum += (uint16)tx_size[i];
rsum += (uint16)rx_size[i];
TXMEM_SIZE[i] = ((uint32)tx_size[i]) << 10;
RXMEM_SIZE[i] = ((uint32)rx_size[i]) << 10;
}
if( (ssum % 8) || ((ssum + rsum) != 128) )
{
#ifdef __DEF_IINCHIP_DBG__
printf("Illegal Memory Allocation\r\n");
#endif
return 0;
}
IINCHIP_WRITE(TMSR0,tx_size[0]);
IINCHIP_WRITE(TMSR1,tx_size[1]);
IINCHIP_WRITE(TMSR2,tx_size[2]);
IINCHIP_WRITE(TMSR3,tx_size[3]);
IINCHIP_WRITE(TMSR4,tx_size[4]);
IINCHIP_WRITE(TMSR5,tx_size[5]);
IINCHIP_WRITE(TMSR6,tx_size[6]);
IINCHIP_WRITE(TMSR7,tx_size[7]);
IINCHIP_WRITE(RMSR0,rx_size[0]);
IINCHIP_WRITE(RMSR1,rx_size[1]);
IINCHIP_WRITE(RMSR2,rx_size[2]);
IINCHIP_WRITE(RMSR3,rx_size[3]);
IINCHIP_WRITE(RMSR4,rx_size[4]);
IINCHIP_WRITE(RMSR5,rx_size[5]);
IINCHIP_WRITE(RMSR6,rx_size[6]);
IINCHIP_WRITE(RMSR7,rx_size[7]);
for(i=0; i <ssum/8 ; i++)
{
mem_cfg <<= 1;
mem_cfg |= 1;
}
IINCHIP_WRITE(MTYPER,(uint8)(mem_cfg >> 8));
IINCHIP_WRITE(MTYPER1,(uint8)(mem_cfg & 0xff));
#ifdef __DEF_IINCHIP_DBG__
printf("Total TX Memory Size = %dKB\r\n",ssum
);
printf("Total RX Memory Size = %dKB\r\n",rsum
);
printf("Ch : TX SIZE : RECV SIZE\r\n");
printf("%02d : %07dKB : %07dKB \r\n", 0, IINCHIP_READ
(TMSR0
),IINCHIP_READ
(RMSR0
));
printf("%02d : %07dKB : %07dKB \r\n", 1, IINCHIP_READ
(TMSR1
),IINCHIP_READ
(RMSR1
));
printf("%02d : %07dKB : %07dKB \r\n", 2, IINCHIP_READ
(TMSR2
),IINCHIP_READ
(RMSR2
));
printf("%02d : %07dKB : %07dKB \r\n", 3, IINCHIP_READ
(TMSR3
),IINCHIP_READ
(RMSR3
));
printf("%02d : %07dKB : %07dKB \r\n", 4, IINCHIP_READ
(TMSR4
),IINCHIP_READ
(RMSR4
));
printf("%02d : %07dKB : %07dKB \r\n", 5, IINCHIP_READ
(TMSR5
),IINCHIP_READ
(RMSR5
));
printf("%02d : %07dKB : %07dKB \r\n", 6, IINCHIP_READ
(TMSR6
),IINCHIP_READ
(RMSR6
));
printf("%02d : %07dKB : %07dKB \r\n", 7, IINCHIP_READ
(TMSR7
),IINCHIP_READ
(RMSR7
));
printf("\r\nMTYPER=%02x%02x\r\n",IINCHIP_READ
(MTYPER0
),IINCHIP_READ
(MTYPER1
));
#endif
return 1;
}
uint32 wiz_write_buf(SOCKET s,uint8* buf,uint32 len)
{
#if (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_DIRECT_MODE__)
#if (__DEF_IINCHIP_BUF_OP__ == __DEF_C__)
uint32 idx=0;
// M_08082008
IINCHIP_CRITICAL_SECTION_ENTER();
for (idx = 0; idx < len; idx+=2)
{
*((vuint8*)Sn_TX_FIFOR0(s)) = *(buf+idx);
*((vuint8*)Sn_TX_FIFOR1(s)) = *(buf+idx+1);
}
// M_08082008
IINCHIP_CRITICAL_SECTION_EXIT();
#elif (__DEF_IINCHIP_BUF_OP__ == __DEF_MCU_DEP_DMA__)
#error "You should do implement this block."
#endif
#elif (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_INDIRECT_MODE__)
#if (__DEF_IINCHIP_BUF_OP__ == __DEF_C__) */
uint32 idx=0;
IINCHIP_CRITICAL_SECTION_ENTER();
*((vuint8*)IDM_AR0) = Sn_TX_FIFOR0(s);
*((vuint8*)IDM_AR1) = Sn_TX_FIFOR1(s);
for (idx = 0; idx < len; idx+=2)
{
*((vuint8*)IDM_DR0) = *((uint8*)(buf+idx));
*((vuint8*)IDM_DR1) = *((uint8*)(buf+idx+1));
}
IINCHIP_CRITICAL_SECTION_EXIT();
#elif (__DEF_IINCHIP_BUF_OP__ == __DEF_MCU_DEP_DMA__)
#error "You should do implement this block."
#else
#error "Undefined __DEF_IINCHIP_BUF_OP__"
#endif
#else
#error "Undefined __DEF_IINCHIP_ADDRESS_MODE__"
#endif
return len;
}
uint32 wiz_read_buf(SOCKET s, uint8* buf,uint32 len)
{
#if (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_DIRECT_MODE__)
#if (__DEF_IINCHIP_BUF_OP__ == __DEF_C__)
uint32 idx;
// M_08082008
IINCHIP_CRITICAL_SECTION_ENTER();
for (idx = 0; idx < len; idx+=2)
{
*(buf+idx) = *((vuint8*)Sn_RX_FIFOR0(s));
*(buf+idx+1) = *((vuint8*)Sn_RX_FIFOR1(s));
}
// M_08082008
IINCHIP_CRITICAL_SECTION_EXIT();
#elif (__DEF_IINCHIP_BUF_OP__ == __DEF_MCU_DEP_DMA__)
#error "You should do implement this block."
#else
#error "Undefined __DEF_IINCHIP_BUF_OP__"
#endif
#elif (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_INDIRECT_MODE__)
#if (__DEF_IINCHIP_BUF_OP__ == __DEF_C__) */
uint32 idx=0;
IINCHIP_CRITICAL_SECTION_ENTER();
*((vuint8*)IDM_AR0) = Sn_RX_FIFOR0(s);
*((vuint8*)IDM_AR1) = Sn_RX_FIFOR1(s);
for (idx = 0; idx < len; idx+=2)
{
*((uint8*)(buf+idx)) = *((vuint8*)IDM_DR0);
*((uint8*)(buf+idx+1)) = *((vuint8*)IDM_DR1);
}
IINCHIP_CRITICAL_SECTION_EXIT();
#elif (__DEF_IINCHIP_BUF_OP__ == __DEF_MCU_DEP_DMA__)
#error "You should do implement this block."
#else
#error "Undefined __DEF_IINCHIP_BUF_OP__"
#endif
#else
#error "Undefined __DEF_IINCHIP_ADDRESS_MODE__"
#endif
return len;
}
uint32 getIINCHIP_TxMAX(SOCKET s)
{
return TXMEM_SIZE[s];
}
uint32 getIINCHIP_RxMAX(SOCKET s)
{
return RXMEM_SIZE[s];
}
// This statement is commented for using 'Doxygen'.
//#ifdef __DEF_IINCHIP_PPP__
#define PPP_OPTION_BUF_LEN 64
uint8 pppinit_in(uint8 * id, uint8 idlen, uint8 * passwd, uint8 passwdlen)
{
uint8 loop_idx = 0;
uint8 isr = 0;
uint8 buf[PPP_OPTION_BUF_LEN];
uint32 len;
uint8 str[PPP_OPTION_BUF_LEN];
uint8 str_idx,dst_idx;
// PHASE1. PPPoE Discovery //
// start to connect pppoe connection
printf("-- PHASE 1. PPPoE Discovery process --");
setSn_CR(0,Sn_CR_PCON);
wait_10ms(100);
// check if PPPoE discovery phase is success or not
loop_idx = 0;
while (!(getSn_IR(0) & Sn_IR_PNEXT))
{
if (loop_idx++ == 10) // timeout
{
printf("timeout before LCP\r\n");
return 3;
}
wait_10ms(100);
}
setSn_IR(0,Sn_IR_PNEXT);
// PHASE2. LCP process //
printf("-- PHASE 2. LCP process --");
{
// 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;
}
wiz_write_buf(0,buf, 0x06);
setSn_TX_WRSR(0,0x06);
setSn_CR(0,Sn_CR_PCR); // send LCP request to PPPoE server
wait_10ms(100);
while (!((isr = getSn_IR(0)) & Sn_IR_PNEXT))
{
if (isr & Sn_IR_PRECV) // Not support option
{
len = getSn_RX_RSR(0);
if ( len > 2 )
{
wiz_read_buf(0,str, 2);
len = ((uint16)str[0] << 8) + str[1];
wiz_read_buf(0,(str+2), len);
setSn_CR(0,Sn_CR_RECV);
// get option length
len = (uint32)str[4]; len = ((len & 0xff) << 8) + (uint32)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((uint8 *)(buf
+dst_idx
), (uint8 *)(str
+str_idx
), str
[str_idx
+1]);
dst_idx += str[str_idx+1]; str_idx += str[str_idx+1];
}
} while (str_idx != len);
// send LCP REJECT packet
wiz_write_buf(0,buf, dst_idx);
setSn_TX_WRSR(0,dst_idx);
setSn_CR(0,Sn_CR_PCJ);
setSn_IR(0,Sn_IR_PRECV);
}
}
if (loop_idx++ == 10) // timeout
{
printf("timeout after LCP\r\n");
return 3;
}
wait_10ms(100);
}
setSn_IR(0,Sn_IR_PNEXT);
// PHASE 3. PPPoE Authentication //
printf("-- PHASE 3. PPPoE Authentication mode --\r\n");
printf("Authentication protocol : %04x, ", getPATR
());
loop_idx = 0;
if (getPATR() == 0xC023) // PAP type
{
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((uint8 *)(buf
+loop_idx
), (uint8 *)(id
), idlen
); loop_idx
+= idlen
;
buf[loop_idx] = passwdlen; loop_idx++;
memcpy((uint8 *)(buf
+loop_idx
), (uint8 *)(passwd
), passwdlen
); loop_idx
+= passwdlen
;
wiz_write_buf(0,buf, loop_idx);
setSn_TX_WRSR(0,loop_idx);
setSn_CR(0,Sn_CR_PCR);
wait_10ms(100);
}
else if (getPATR() == 0xC223) // CHAP type
{
uint8 chal_len;
md5_ctx context;
uint8 digest[16];
len = getSn_RX_RSR(0);
if ( len > 2 )
{
wiz_read_buf(0,str,2);
len = ((uint32)str[0] << 8) + (uint32)str[1];
wiz_read_buf(0, str, len);
setSn_CR(0,Sn_CR_RECV);
#ifdef __DEF_IINCHIP_DBG__
{
int16 i;
for (i
= 0; i
< 32; i
++) printf ("%02X ", str
[i
]);
}
#endif
// str is C2 23 xx CHAL_ID xx xx CHAP_LEN CHAP_DATA
// index 0 1 2 3 4 5 6 7 ...
buf[loop_idx] = str[3]; loop_idx++; // chal_id
memcpy((uint8 *)(buf
+loop_idx
), (uint8 *)(passwd
), passwdlen
); loop_idx
+= passwdlen
; //passwd
chal_len = str[6]; // chal_id
memcpy((uint8 *)(buf
+loop_idx
), (uint8 *)(str
+7), chal_len
); loop_idx
+= chal_len
; //challenge
buf[loop_idx] = 0x80;
#ifdef __DEF_IINCHIP_DBG__
{
int16 i;
for (i
= 0; i
< 64; i
++) printf ("%02X ", buf
[i
]);
}
#endif
md5_init(&context);
md5_update(&context, buf, loop_idx);
md5_final(digest, &context);
#ifdef __DEF_IINCHIP_DBG__
{
uint i;
for (i
= 0; i
< 16; i
++) printf ("%02X", digest
[i
]);
}
#endif
loop_idx = 0;
buf[loop_idx] = 16; loop_idx++; // hash_len
memcpy((uint8 *)(buf
+loop_idx
), (uint8 *)(digest
), 16); loop_idx
+= 16; // hashed value
memcpy((uint8 *)(buf
+loop_idx
), (uint8 *)(id
), idlen
); loop_idx
+= idlen
; // id
wiz_write_buf(0,buf, loop_idx);
setSn_TX_WRSR(0,loop_idx);
setSn_CR(0,Sn_CR_PCR);
wait_10ms(100);
}
}
else
{
#ifdef __DEF_IINCHIP_DBG__
printf("Not support PPP Auth type: %.4x\r\n",getPATR
());
#endif
return 4;
}
printf("-- Waiting for PPPoE server's admission --");
loop_idx = 0;
while (!((isr = getSn_IR(0)) & Sn_IR_PNEXT))
{
if (isr & Sn_IR_PFAIL)
{
printf("failed\r\nReinput id, password..\r\n");
return 2;
}
if (loop_idx++ == 10) // timeout
{
printf("timeout after PAP\r\n");
return 3;
}
wait_10ms(100);
}
setSn_IR(0,Sn_IR_PNEXT);
// PHASE 4. IPCP process //
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;
wiz_write_buf(0,buf, 6);
setSn_TX_WRSR(0,6);
setSn_CR(0,Sn_CR_PCR);
wait_10ms(100);
loop_idx = 0;
while (1)
{
if (getSn_IR(0) & Sn_IR_PRECV)
{
len = getSn_RX_RSR(0);
if ( len > 2 )
{
wiz_read_buf(0,str,2);
len = ((uint32)str[0] << 8) + (uint32)str[1];
wiz_read_buf(0, str, len);
setSn_CR(0,Sn_CR_RECV);
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((uint8 *)(buf
+dst_idx
), (uint8 *)(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);
wiz_write_buf(0,buf, dst_idx);
setSn_TX_WRSR(0,dst_idx);
setSn_CR(0,Sn_CR_PCR); // send ipcp request
wait_10ms(100);
break;
}
}
setSn_IR(0,Sn_IR_PRECV);
}
if (loop_idx++ == 10) // timeout
{
printf("timeout after IPCP\r\n");
return 3;
}
wait_10ms(100);
wiz_write_buf(0, buf, 6);
setSn_TX_WRSR(0,6);
setSn_CR(0,Sn_CR_PCR); //ipcp re-request
}
loop_idx = 0;
while (!(getSn_IR(0) & Sn_IR_PNEXT))
{
if (loop_idx++ == 10) // timeout
{
printf("timeout after IPCP NAK\r\n");
return 3;
}
wait_10ms(100);
setSn_CR(0,Sn_CR_PCR); // send ipcp request
}
setSn_IR(0,Sn_IR_PNEXT);
return 1;
// after this function, the pppoe server's mac address and pppoe session id is saved in PHAR and PSIDR repectly.
}
uint8 pppinit(uint8 *id, uint8 idlen, uint8 *passwd, uint8 passwdlen)
{
uint8 ret;
uint8 isr;
// PHASE0. PPPoE setup
printf("-- PHASE 0. PPPoE setup process --\r\n");
setMR(getMR()|MR_PPPoE); // set PPPoE mode
setMR(getMR()|MR_FS); // If little-endian, set MR_FS. Otherwise, comment.
isr = getSn_IR(0);
setSn_IR(0,isr); // clear the previous value of Sn_IR(0)
setPTIMER(200); // set LPC request time to 5 seconds
setPMAGICR(0x01); // set the magic number
setSn_MR(0, Sn_MR_PPPoE); // set Sn_MR(0) to PPPoE mode
setSn_CR(0,Sn_CR_OPEN); //open SOCKET0 with PPPoE mode
ret = pppinit_in(id, idlen, passwd, passwdlen); // process the PPPoE message
setSn_CR(0, Sn_CR_CLOSE); // close PPPoE SOCKET0
return ret;
}
void pppterm(uint8 *mac, uint16 sessionid)
{
uint8 isr;
#ifdef __DEF_IINCHIP_DBG__
#endif
// set PPPoE mode
setMR(getMR() | MR_PPPoE);
// set pppoe server's mac address and session id
// must be setted these value.
setSn_DHAR(0, mac);
setSn_DPORTR(0,sessionid);
// clear the previous value of Sn_IR(0)
isr = getSn_IR(0);
setSn_IR(0,isr);
//open SOCKET0 with PPPoE mode
setSn_MR(0, Sn_MR_PPPoE);
setSn_CR(0,Sn_CR_OPEN);
while(getSn_SSR(0) != SOCK_PPPoE)
// close PPPoE connection
setSn_CR(0,Sn_CR_PDISCON);
wait_10ms(100);
// close socket
setSn_CR(0,Sn_CR_CLOSE);
#ifdef __DEF_IINCHIP_DBG__
printf("pppterm() end ..\r\n");
#endif
}
// This statement is commented for using 'Doxygen'.
//#endif
void wait_1us(uint32 us)
{
uint32 i,j;
for(i = 0; i < us ; i++)
{
for(j = 0; j < 100; j++);
}
}
void wait_1ms(uint32 ms)
{
uint32 i;
for(i = 0; i < ms ; i++)
{
wait_1us(1000);
}
}
void wait_10ms(uint32 ms)
{
uint32 i;
for(i = 0; i < ms ; i++)
{
wait_1ms(10);
}
}