📄 main.c
字号:
//------------------------------------------------------------------------------
// main.c
//------------------------------------------------------------------------------
// Copyright (C) 2005 Silicon Laboratories, Inc.
//
// Date: 05/16/06 13:16:02
// Target: C8051F34x
// Version: 1.31
//
// Description:
//
// This is a UDP 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 UDP Echo Server, set SERVER_MODE in main.c to 1.
// To run the example as a UDP 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 (UDP_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. If running in Client mode, place the IP address of the PC that will
// be echoing the UDP packets in IP_DEST_ADDR in mn_userconst.h.
//
// 5. Connect to the C8051f340.
//
// 6. Compile and build the project code.
//
// 7. Download the code to the C8051f340.
//
// 8. If running in Client mode, run UDP_SVR.exe on the PC receiving the
// call. Then press "Go." Once the Ethernet controller has initialized,
// UDP_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 UDP_SVR.exe and send it
// back, and so forth.
//
// 9. If running in Server mode, press "Go." Then run UDP_CLI.exe on the PC.
// By default, UDP_CLI.exe will send data to 216.233.5.26. If the
// embedded Ethernet controller is using a different IP address,
// execute UDP_CLI.exe from the command line using this syntax:
//
// UDP_CLI.exe XXX.XXX.XXX.XXX
//
// where XXX.XXX.XXX.XXX is the IP address of the embedded Ethernet controller.
// UDP_CLI.exe will send out a string and wait for the embedded Ethernet
// controller to echo it back. UDP_CLI.exe will then take the received string
// and send it to the embedded Ethernet controller, and so forth.
//
// 10. Once the UDP 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 UDP(void);
//-----------------------------------------------------------------------------
// Constant Definitions
//-----------------------------------------------------------------------------
#define SERVER_MODE 0
#define DATA_BUFF_LEN 40
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
static byte ECHOSTRING[]= "THIS IS COMING FROM SILABS ETHERNET-DK";
byte data_buff[DATA_BUFF_LEN];
//-----------------------------------------------------------------------------
// Main Routine
//-----------------------------------------------------------------------------
void main(void)
{
int retval;
// Disable watchdog timer
PCA0MD = 0x00;
// Initialize the MCU
PORT_Init();
SYSCLK_Init();
EMIF_Init();
while(1)
{
// Initialize the TCP/IP stack.
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();
// Run the UDP example.
UDP();
// 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;
do
{
// mn_ether_init() initializes the Ethernet controller.
// AUTO_NEG indicates that the controller will auto-negotiate.
retval = mn_ether_init(AUTO_NEG, 0, 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)
{
while(!link_status && !ether_reset);
}
// If retval is less than zero and is not LINK_FAIL, there is a
// hardware error.
else if (retval < 0)
{
// Verify that the Ethernet controller is connected and powered properly.
// Verity that the EMIF has been configured at a speed compatible with the
// Ethernet controller.
while(1);
}
}while(retval < 0);
return (1);
}
//-----------------------------------------------------------------------------
// Application Functions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// UDP
//-----------------------------------------------------------------------------
//
void UDP(void)
{
SCHAR socket_no;
PSOCKET_INFO socket_ptr;
byte *data_ptr;
word16 data_len;
int status;
#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,NO_OPEN,PROTO_UDP,\
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,NO_OPEN,PROTO_UDP,\
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;
if (data_ptr != PTR_NULL)
status = mn_send(socket_no,data_ptr,data_len);
if (status < 0)
{
data_len = 0;
break;
}
status = mn_recv(socket_no,data_buff,DATA_BUFF_LEN);
if (status < 0 && status != SOCKET_TIMED_OUT)
{
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 + -