📄 main.c
字号:
//------------------------------------------------------------------------------
// main.c
//------------------------------------------------------------------------------
// Copyright (C) 2005 Silicon Laboratories, Inc.
//
// Date: 05/16/06 13:15:54
// Target: C8051F34x
// Version: 1.31
//
// Description:
//
// This is a TCP example.
// This code runs on a C8051F340 connected to a CP2200 via AB4 board.
//
// This file contains the main routine, MCU initialization code, and
// callback functions used by the TCP/IP Library.
//
// Steps for running this example code:
//
// 1. To run the example as a TCP Echo Server, set SERVER_MODE in main.c to 1.
// To run the example as a TCP Echo Client, set SERVER_MODE to 0.
//
// 2. If running in Client mode, place the IP address of the PC which will
// be running the test application (TCP_SVR.exe) in IP_DEST_ADDR in
// mn_userconst.h.
//
// 3. Place the IP address of the embedded Ethernet controller (C8051F340
// and CP2200) in IP_SRC_ADDR in mn_userconst.h.
//
// 4. Connect to the C8051F340.
//
// 5. Compile and build the project code.
//
// 6. Download the code to the C8051F340.
//
// 7. If running in Client mode, run TCP_SVR.exe on the PC receiving the
// call. Then press "Go." Once the Ethernet controller has initialized,
// TCP_SVR.exe will wait for the embedded Ethernet controller to send
// a string, then echo the received string back. The embedded Ethernet
// controller will then take the string from TCP_SVR.exe and send it
// back, and so forth.
//
// 8. If running in Server mode, press "Go." Then run TCP_CLI.exe on the PC.
// By default, TCP_CLI.exe will send data to 216.233.5.26. If the
// embedded Ethernet controller is using a different IP address,
// execute TCP_CLI.exe from the command line using this syntax:
//
// TCP_CLI.exe XXX.XXX.XXX.XXX
//
// where XXX.XXX.XXX.XXX is the IP address of the embedded Ethernet controller.
// TCP_CLI.exe will send out a string and wait for the embedded Ethernet
// controller to echo it back. TCP_CLI.exe will then take the received string
// and send it to the embedded Ethernet controller, and so forth.
//
// 9. Once the TCP example has terminated, the user may ping the C8051F340
// at the IP address defined in IP_DEST_ADDR.
//
#include "mn_userconst.h" // TCP/IP Library Constants
#include "mn_stackconst.h" // TCP/IP Library Constants
#include "mn_errs.h" // Library Error Codes
#include "mn_defs.h" // Library Type definitions
#include "mn_funcs.h" // Library Function Prototypes
#include <c8051F340.h> // Device-specific SFR Definitions
#include <string.h>
//------------------------------------------------------------------------------
// Function Prototypes
//------------------------------------------------------------------------------
// Initialization Routines
void PORT_Init (void);
void SYSCLK_Init (void);
void EMIF_Init(void);
int establish_network_connection();
// Application Functions
void TCP(void);
unsigned char TCP_ToLISTEN(unsigned int timeout);
unsigned char Tcp_Senddata(unsigned int dlen, unsigned char xdata *sdata);
unsigned char Tcp_Recdata(unsigned int rlen, unsigned char xdata *rdata,unsigned char timeout);
//-----------------------------------------------------------------------------
// Constant Definitions
//-----------------------------------------------------------------------------
#define SERVER_MODE 0
#define DATA_BUFF_LEN 40
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
static byte ECHOSTRING[]= "for listen";
static byte ECHOSTRING1[]= "THIS IS COMING FROM SILABS ETHERNET-DK";
byte data_buff[DATA_BUFF_LEN];
SCHAR socket_no;
bit tcpopened;
//-----------------------------------------------------------------------------
// Main Routine
//-----------------------------------------------------------------------------
void main(void)
{
// int retval;
word16 data_len;
unsigned char xdata rdatatemp[30];
// unsigned int i;
data_len = strlen((char *)ECHOSTRING1);
// Disable watchdog timer
PCA0MD = 0x00;
// Initialize the MCU
PORT_Init();
SYSCLK_Init();
EMIF_Init();
if (mn_init() < 0)
{
// If code execution enters this while(1) loop, the stack failed to initialize.
// Verify that all boards are connected and powered properly.
while(1);
}
// Connect to the network
establish_network_connection();
while(1)
{
// Initialize the TCP/IP stack.
// Run the TCP example
// TCP();
if(!TCP_ToLISTEN(5))
{
Tcp_Senddata(data_len,ECHOSTRING1);
Tcp_Recdata(10,rdatatemp,1);
}
// Start the Application Layer Services
// If this routine exits, check the return value for an error code.
//retval = mn_server();
}
}
//-----------------------------------------------------------------------------
// establish_network_connection
//-----------------------------------------------------------------------------
//
// This function calls mn_ether_init() to initialize the CP2200 and attach to
// the network.
//
// If there is a network connection, the function returns 1.
//
// In the call to mn_ether_init(), NUM_AUTONEG_ATTEMPTS is set to 0, so the
// function will not return until it successfully auto-negotiates.
//
// mn_ether_init() will not be a blocking call if NUM_AUTONEG_ATTEMPTS is set
// to a value greater than 0.
//
int establish_network_connection()
{
int retval;
// mn_ether_init() initializes the Ethernet controller.
// AUTO_NEG indicates that the controller will auto-negotiate.
retval = mn_ether_init(AUTO_NEG, 1, 0);
// If there is no link, poll link_status until it sets or the
// CP2200 resets and then call mn_ether_init() again.
if (retval == LINK_FAIL)
{
return(0);
}
// If retval is less than zero and is not LINK_FAIL, there is a
// hardware error.
else if (retval < 0)
{
return(0);
}
else
return (1);
}
//-----------------------------------------------------------------------------
// Application Functions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// TCP
//-----------------------------------------------------------------------------
//
unsigned char TCP_ToLISTEN(unsigned int timeout)
{
unsigned int i,j;
PSOCKET_INFO socket_ptr;
byte *data_ptr;
word16 data_len;
int status;
data_ptr = ECHOSTRING;
data_len = strlen((char *)ECHOSTRING);
if(tcpopened)
socket_ptr = MK_SOCKET_PTR(socket_no);
for(i=0;i<(10+10*timeout);i++)
{
if(link_status)
{
if(tcpopened)
{
if(socket_ptr->tcp_state == TCP_ESTABLISHED)
return(0);
if (data_ptr != PTR_NULL)
{
status = mn_send(socket_no,data_ptr,data_len);
if (status > 0 && socket_ptr->recv_len > 0)
{
data_ptr = socket_ptr->recv_ptr;
data_len = socket_ptr->recv_len;
}
}
if (socket_ptr->tcp_state == TCP_CLOSED)
{
tcpopened=0;
}
do
{
status = mn_recv(socket_no,data_buff,DATA_BUFF_LEN);
}while (status == NEED_TO_LISTEN);
// if we got something, send back what we got
if (status > 0)
{
data_ptr = socket_ptr->recv_ptr;
data_len = socket_ptr->recv_len;
}
}
else
{
socket_no = mn_open(null_addr,ECHO_PORT,0,NO_OPEN,PROTO_TCP,\
STD_TYPE,data_buff,DATA_BUFF_LEN);
if(socket_no>=0)
tcpopened=1;
}
}
else
{
mn_ether_init(AUTO_NEG, 1, 0);
for(j=0;j<100;j++);
}
}
}
unsigned char Tcp_Senddata(unsigned int dlen, unsigned char xdata *sdata)
{
int status;
status = mn_send(socket_no,sdata,dlen);
if (status > 0)
return(0);
return(1);
}
unsigned char Tcp_Recdata(unsigned int rlen, unsigned char xdata *rdata,unsigned char timeout)
{
PSOCKET_INFO socket_ptr;
int status;
int rlentemp;
unsigned char *data_ptr1;
int i;
int ii;
rlentemp=0;
socket_ptr = MK_SOCKET_PTR(socket_no);
for(ii=0;ii<(1+10*timeout);ii++)
{
rev: if(socket_ptr->recv_len > 0)
{ data_ptr1= socket_ptr->recv_ptr;
for(i=0;i<socket_ptr->recv_len;i++)
rdata[rlentemp++] = *data_ptr1++;
//rlentemp += socket_ptr->recv_len;
socket_ptr->recv_len=0;
if(rlentemp>=rlen)
return(0);
}
status = mn_recv(socket_no,data_buff,DATA_BUFF_LEN);
if(status>0)
goto rev;
}
return(1);
}
void TCP(void)
{
SCHAR socket_no;
PSOCKET_INFO socket_ptr;
byte *data_ptr;
word16 data_len;
int status;
unsigned char da[40];
unsigned int i;
#if SERVER_MODE
// When dest_ip is null_addr any IP address is allowed to connect
socket_no = mn_open(null_addr,ECHO_PORT,0,PASSIVE_OPEN,PROTO_TCP,\
STD_TYPE,data_buff,DATA_BUFF_LEN);
data_ptr = PTR_NULL;
data_len = 0;
#else
socket_no = mn_open(ip_dest_addr,DEFAULT_PORT,ECHO_PORT,ACTIVE_OPEN,PROTO_TCP,\
STD_TYPE,data_buff,DATA_BUFF_LEN);
data_ptr = ECHOSTRING;
data_len = strlen((char *)ECHOSTRING);
#endif
if (socket_no < 0)
{
return;
}
socket_ptr = MK_SOCKET_PTR(socket_no); // get pointer to the socket
while(1)
{
status = 0;
/* mn_send sends the data and waits for an ACK. Some echo servers will
return the ACK and the data in the same packet, so we need to handle
that case. */
if (data_ptr != PTR_NULL)
{
status = mn_send(socket_no,data_ptr,data_len);
if (status > 0 && socket_ptr->recv_len > 0)
{
data_ptr = socket_ptr->recv_ptr;
data_len = socket_ptr->recv_len;
for(i=0;i<40;i++)
da[i]=0;
for(i=0;i<40;i++)
da[i]=*data_ptr++;
socket_ptr->recv_len=0;
socket_ptr->recv_len=0;
continue;
}
}
if (status < 0 || socket_ptr->tcp_state == TCP_CLOSED)
{
break;
}
do
{
status = mn_recv(socket_no,data_buff,DATA_BUFF_LEN);
}while (status == NEED_TO_LISTEN);
if (status < 0)
{
break;
}
// if we got something, send back what we got
if (status > 0)
{
data_ptr = socket_ptr->recv_ptr;
data_len = socket_ptr->recv_len;
}
}
mn_abort(socket_no);
}
//-----------------------------------------------------------------------------
// Initialization Routines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Interrupts, Crossbar and GPIO ports
//
void PORT_Init (void)
{
IT01CF = 0x03; // Enable Interrupt 0 on P0.3
TCON &= ~0x01; // Make /INT0 level triggered
XBR0 = 0x01; // Enable UART on P0.4(TX) and P0.5(RX)
XBR1 = 0x40; // Enable crossbar and enable
// weak pull-ups
P0MDOUT |= 0x10; // enable UTX as push-pull output
P1MDOUT |= 0xD8; // /WR and /RD are push-pull
// AB4 LEDs are push-pull
P2MDOUT |= 0xFF;
P3MDOUT |= 0xFF;
P4MDOUT |= 0xFF;
}
//-----------------------------------------------------------------------------
// EMIF_Init
//-----------------------------------------------------------------------------
//
// Configure the External Memory Interface for both on and off-chip access.
//
void EMIF_Init (void)
{
EMI0CF = 0x1B; // non-muxed mode; split mode
// with bank select
EMI0TC = EMIF_TIMING; // This constant may be modified
// according to SYSCLK to meet the
// timing requirements for the CP2200
EMI0CN = BASE_ADDRESS; // Page of XRAM accessed by EMIF
}
//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock.
//
void SYSCLK_Init (void)
{
int i;
OSCICN |= 0x03; // Configure internal oscillator for
// its maximum frequency
CLKMUL = 0x00; // Reset Clock Multiplier and select
// internal oscillator as input source
CLKMUL |= 0x80; // Enable the Clock Multiplier
for(i = 0; i < 256; i++); // Delay at least 5us
CLKMUL |= 0xC0; // Initialize the Clock Multiplier
while(!(CLKMUL & 0x20)); // Wait for MULRDY => 1
RSTSRC = 0x06; // Enable missing clock detector
// and VDD monitor
FLSCL |= 0x10; // Set Flash Scale for 48MHz
CLKSEL |= 0x03; // Select output of clock multiplier
// as the system clock.
}
//-----------------------------------------------------------------------------
// ether_reset_low
//-----------------------------------------------------------------------------
//
// This routine drives the reset pin of the ethernet controller low.
//
void ether_reset_low()
{
P1 &= ~0x01; // Pull reset low
}
//-----------------------------------------------------------------------------
// ether_reset_high
//-----------------------------------------------------------------------------
//
// This routine places the reset pin in High-Z allowing it to be pulled up
// using the external pull-up resistor.
//
// Additionally, this routine waits for the reset pin to read high before
// exiting.
//
void ether_reset_high (void)
{
P1 |= 0x01; // Allow /RST to rise
while(!(P1 & 0x01)); // Wait for /RST to go high
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -