/******************************************************************************
* [url=home.php?mod=space&uid=288409]@file[/url] main.c
* [url=home.php?mod=space&uid=895143]@version[/url] V1.00
* $Revision: 8 $
* $Date: 14/05/30 5:59p $
* [url=home.php?mod=space&uid=247401]@brief[/url] This Ethernet sample tends to get a DHCP lease from DHCP
* server. And use 192.168.10.10 as IP address it failed to
* get a lease. After IP address configured, this sample can
* reply to PING packets.
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "NUC472_442.h"
#include "uip.h"
#include "uip_arp.h"
#include "timer.h"
#define PLLCON_SETTING CLK_PLLCON_84MHz_XTAL
#define PLL_CLOCK 84000000
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#ifndef NULL
#define NULL (void *)0
#endif /* NULL */
// Our MAC address
uint8_t g_au8MacAddr[6] = {0x00, 0x00, 0x00, 0x59, 0x16, 0x88};
clock_time_t g_Time = 0;
/**
* @brief This function handles SysTick Handler.
* @param None
* @retval None
*/
void SysTick_Handler(void)
{
g_Time++;
if (g_Time == 0xFFFFFFFF)
{
g_Time = 0;
}
}
/**
* @brief EMAC Tx interrupt handler.
* @param None
* [url=home.php?mod=space&uid=266161]@return[/url] None
*/
void EMAC_TX_IRQHandler(void)
{
// Clean up Tx resource occupied by previous sent packet(s)
EMAC_SendPktDone();
}
void SYS_Init(void)
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Unlock protected registers */
SYS_UnlockReg();
/* Enable External XTAL (4~24 MHz) */
CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
/* Waiting for 12MHz clock ready */
CLK_WaitClockReady( CLK_STATUS_HXTSTB_Msk);
/* Switch HCLK clock source to HXT */
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HXT,CLK_CLKDIV0_HCLK(1));
/* Set PLL to power down mode and PLL_STB bit in CLKSTATUS register will be cleared by hardware.*/
CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
/* Set PLL frequency */
CLK->PLLCTL = CLK_PLLCTL_84MHz_HXT;
/* Waiting for clock ready */
CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);
/* Switch HCLK clock source to PLL */
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL,CLK_CLKDIV0_HCLK(1));
/* Enable IP clock */
CLK_EnableModuleClock(UART0_MODULE);
CLK_EnableModuleClock(EMAC_MODULE);
/* Select IP clock source */
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HXT, CLK_CLKDIV0_UART(1));
// Configure MDC clock rate to HCLK / (127 + 1) = 656 kHz if system is running at 84 MHz
CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(127));
/* Update System Core Clock */
/* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
SystemCoreClockUpdate();
/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*---------------------------------------------------------------------------------------------------------*/
/* Set GPG multi-function pins for UART0 RXD and TXD */
SYS->GPG_MFPL = SYS_GPG_MFPL_PG1MFP_UART0_RXD | SYS_GPG_MFPL_PG2MFP_UART0_TXD ;
// Configure RMII pins
SYS->GPC_MFPL = SYS_GPC_MFPL_PC0MFP_EMAC_REFCLK |
SYS_GPC_MFPL_PC1MFP_EMAC_MII_RXERR |
SYS_GPC_MFPL_PC2MFP_EMAC_MII_RXDV |
SYS_GPC_MFPL_PC3MFP_EMAC_MII_RXD1 |
SYS_GPC_MFPL_PC4MFP_EMAC_MII_RXD0 |
SYS_GPC_MFPL_PC6MFP_EMAC_MII_TXD0 |
SYS_GPC_MFPL_PC7MFP_EMAC_MII_TXD1;
SYS->GPC_MFPH = SYS_GPC_MFPH_PC8MFP_EMAC_MII_TXEN;
// Enable high slew rate on all RMII pins
PC->SLEWCTL |= 0x1DF;
// Configure MDC, MDIO at PB14 & PB15
SYS->GPB_MFPH = SYS_GPB_MFPH_PB14MFP_EMAC_MII_MDC | SYS_GPB_MFPH_PB15MFP_EMAC_MII_MDIO;
/* Lock protected registers */
SYS_LockReg();
}
int main(void)
{
int i;
uip_ipaddr_t ipaddr;
struct timer periodic_timer, arp_timer;
SYS_Init();
UART_Open(UART0, 115200);
// Select RMII interface by default
EMAC_Open(g_au8MacAddr);
NVIC_EnableIRQ(EMAC_TX_IRQn);
//NVIC_EnableIRQ(EMAC_RX_IRQn);
EMAC_ENABLE_RX();
EMAC_ENABLE_TX();
SysTick_Config(SystemCoreClock / 1000);
timer_set(&periodic_timer, CLOCK_SECOND / 2);
timer_set(&arp_timer, CLOCK_SECOND * 10);
uip_init();
uip_ipaddr(ipaddr, 192,168,0,2);
uip_sethostaddr(ipaddr);
uip_ipaddr(ipaddr, 192,168,0,1);
uip_setdraddr(ipaddr);
uip_ipaddr(ipaddr, 255,255,255,0);
uip_setnetmask(ipaddr);
tcp_client_init();
while(1)
{
EMAC_RecvPkt(uip_buf, ( uint32_t *)&uip_len);
if(uip_len == 0)
{
EMAC_RecvPktDone();
}
if(uip_len > 0)
{
if(BUF->type == htons(UIP_ETHTYPE_IP))
{
uip_arp_ipin();
uip_input();
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if(uip_len > 0)
{
uip_arp_out();
//tapdev_send();
EMAC_SendPkt(uip_buf, uip_len);
}
}
else if(BUF->type == htons(UIP_ETHTYPE_ARP))
{
uip_arp_arpin();
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if(uip_len > 0)
{
EMAC_SendPkt(uip_buf, uip_len);
}
}
EMAC_RecvPktDone();
}
else if(timer_expired(&periodic_timer))
{
timer_reset(&periodic_timer);
for(i = 0; i < UIP_CONNS; i++)
{
uip_periodic(i);
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if(uip_len > 0)
{
uip_arp_out();
EMAC_SendPkt(uip_buf, uip_len);
}
}
#if UIP_UDP
for(i = 0; i < UIP_UDP_CONNS; i++)
{
uip_udp_periodic(i);
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if(uip_len > 0)
{
uip_arp_out();
EMAC_SendPkt(uip_buf, uip_len);
}
}
#endif /* UIP_UDP */
/* Call the ARP timer function every 10 seconds. */
if(timer_expired(&arp_timer))
{
timer_reset(&arp_timer);
uip_arp_timer();
}
}
}
return 0;
}
void uip_log(char *m)
{
printf("uIP log message: %s\n", m);
}
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
|