📄 main.c
字号:
//------------------------------------------------------------------------------
// main.c
//------------------------------------------------------------------------------
// Copyright (C) 2005 Silicon Laboratories, Inc.
//
// Date: 09/21/06 17:25:55
// Target: C8051F02x
// Version: 1.01
//
// Description:
// This Telnet echo server example shows how to use callback functions
// to implement a Telnet (TCP) Echo Server.
//
// This file contains the main routine, MCU initialization code, and
// callback functions used by the TCP/IP Library.
//
// How to test:
//
// 1. Compile, Build, and Download to Target MCU + AB4.
//
// 2. Search for the embedded system using Netfinder. If the embedded system
// did not automatically obtain an IP address through DHCP, then manually
// assign it an IP address.
//
// 3. Select an embedded system in Netfinder and click Hyperterminal.
// You may also use any other Telnet client.
//
// 4. Open the Telnet connection (if not already opened).
//
// 5. All characters received by the echo server will be "echoed" back
// to the terminal application.
//
// Generated by TCP/IP Configuration Wizard Version 3.2
//
#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 "netfinder.h"
#include <c8051F020.h> // Device-specific SFR Definitions
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//-----------------------------------------------------------------------------
sfr16 RCAP2 = 0xca; // Timer2 reload value
sfr16 TMR2 = 0xcc; // Timer2 counter
sfr16 ADC0 = 0xbe; // ADC0 data register
//------------------------------------------------------------------------------
// Global Constants
//------------------------------------------------------------------------------
#define SYSCLK 22118400L // System Clock Frequency in Hz
#define T2_OVERFLOW_RATE 32L // Timer 2 Overflow Rate in Hz
//------------------------------------------------------------------------------
// Function Prototypes
//------------------------------------------------------------------------------
// Initialization Routines
void PORT_Init (void);
void SYSCLK_Init (void);
void EMIF_Init(void);
int establish_network_connection();
void Timer2_Init(void);
//-----------------------------------------------------------------------------
// Main Routine
//-----------------------------------------------------------------------------
void main(void)
{
int retval;
// Disable watchdog timer
WDTCN = 0xde;
WDTCN = 0xad;
// Initialize the MCU
PORT_Init();
SYSCLK_Init();
EMIF_Init();
Timer2_Init();
// Reset the Netfinder Event 1 counter after a Power-On Reset or Pin Reset
// The event1 counter counts how long the device has been powered.
if(RSTSRC & 0x03){
netfinder_reset_event1();
}
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();
// Use DHCP to obtain an IP address.
if (mn_dhcp_start(PTR_NULL, dhcp_default_lease_time) <= 0)
{
// DHCP Error
// The DHCP server did not assign a valid IP address.
// Override DHCP
dhcp_lease.infinite_lease = 1;
dhcp_lease.dhcp_state = DHCP_OK;
// Specify a static IP address
ip_src_addr[0] = 0;
ip_src_addr[1] = 0;
ip_src_addr[2] = 0;
ip_src_addr[3] = 1;
}
// Reset Netfinder event2 counter
// The event2 counter counts how long the device has been on a network.
netfinder_reset_event2();
// Start the Netfinder Service
if( netfinder_start() < 0 )
{
// If code execution enters this while(1) loop, the Netfinder
// service failed to open a UDP socket.
// - Verify that the current library contains UDP.
// - Verify that there are at least two sockets allocated.
while(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;
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);
}
//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Timer2_ISR (T2_OVERFLOW_RATE Hz)
//-----------------------------------------------------------------------------
//
void Timer2_ISR (void) interrupt 5
{
// Define static counters for real time clock (RTC).
static unsigned int RTC_counter = 0;
// Clear Timer 2 Overflow Flag
TF2 = 0;
// Check if one second has passed and update RTC.
if(RTC_counter >= T2_OVERFLOW_RATE){
// Clear counter and update real time clock
RTC_counter = 0;
netfinder_update_RTC();
} else {
// Increment interrupt count
RTC_counter++;
}
}
//-----------------------------------------------------------------------------
// Initialization Routines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Interrupts, Crossbar and GPIO ports
//
void PORT_Init (void)
{
P1MDOUT |= 0x40; // Set P1.6(TB_LED) to push-pull
P2MDOUT |= 0x08; // Set P2.2(AB4_LED1)
P74OUT = 0xFF;
P4 = 0xC0; // /WR, /RD, are high, RESET is low
P5 = 0xFF;
P6 = 0xFF; // P5, P6 contain the address lines
P7 = 0xFF; // P7 contains the data lines
TCON &= ~0x01; // Make /INT0 level triggered
// Enable UART0, CP0, and /INT0. This puts /INT0 on P0.3.
XBR0 = 0x84;
XBR1 = 0x04;
XBR2 = 0x40;
}
//-----------------------------------------------------------------------------
// EMIF_Init
//-----------------------------------------------------------------------------
//
// Configure the External Memory Interface for both on and off-chip access.
//
void EMIF_Init (void)
{
EMI0CF = 0xFB; // Split-mode, non-multiplexed on P0 - P3
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; // delay counter
OSCXCN = 0x67; // start external oscillator with
// 22.1184MHz crystal
for (i=0; i < 256; i++) ; // wait for oscillator to start
while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle
OSCICN = 0x88; // select external oscillator as SYSCLK
// source and enable missing clock
// detector
}
//-----------------------------------------------------------------------------
// Timer2_Init
//-----------------------------------------------------------------------------
//
// This routine initializes Timer 2 to <T2_OVERFLOW_RATE> Hz.
//
void Timer2_Init(void)
{
T2CON = 0x00; // Stop Timer2;
CKCON &= ~0x20; // Use SYSCLK/12 as timebase
// Initialize Reload Value
RCAP2 = -(SYSCLK/12/T2_OVERFLOW_RATE);
TMR2 = RCAP2;
ET2 = 1; // Enable Timer 2 interrupts
TR2 = 1; // Start Timer 2
}
//-----------------------------------------------------------------------------
// ether_reset_low
//-----------------------------------------------------------------------------
//
// This routine drives the reset pin of the ethernet controller low.
//
void ether_reset_low()
{
P4 &= ~0x20; // 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)
{
P4 |= 0x20; // Allow /RST to rise
while(!(P4 & 0x20)); // Wait for /RST to go high
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -