git-svn-id: svn+ssh://oldsvn/home/mlalondesvn/svn/cral@18 3ee9b42a-b53c-0410-a25e-f0b6218d5d5bmaster
parent
104d8333ee
commit
2937810d7c
@ -0,0 +1,16 @@
|
||||
+ How to compile
|
||||
|
||||
Execute the make in the ~/compile folder, then the source code is compiled.
|
||||
|
||||
In the Makefile, the compiler vesion is distinguished by "D__COMPILER_VERSION__" option
|
||||
and compiler version is defined in the types.h file like belows.
|
||||
|
||||
#define __WINAVR_20050214__ 0
|
||||
#define __WINAVR_20060125__ 1
|
||||
#define __WINAVR_20060421__ 2
|
||||
|
||||
According to the compiler version,
|
||||
rename the Makefile_WinAVR_20050214 or Makefile_WinAVR_20060421 file to Makefile
|
||||
|
||||
+ How to Change the interface mode
|
||||
Change the value of the __DEF_IINCHIP_BUS__ in the types.h file.
|
@ -0,0 +1,23 @@
|
||||
+ 컴파일 방법
|
||||
|
||||
~/compile 폴더에서 make 를 실행하면 자동으로 컴파일된다.
|
||||
|
||||
* 만일 다운받은 컴파일러(WinAVR)가 WinAVR-20050214-install.exe 라면,
|
||||
compile폴더의 Makefile_WinAVR_20050214 파일을 Makefile로 복사하고,
|
||||
make하면 에러없이 컴파일 된다.
|
||||
그 외의 상위버전의 경우 Makefile_WinAVR_20060421파일을 Makefile로 복사하고
|
||||
make하면 에러없이 컴파일 된다.
|
||||
|
||||
[ Makefile에서 -D옵션(-D__COMPILER_VERSION__=2)을 통해 define되어 있으며,
|
||||
소스상에서 define(types.h 참고)으로 구분된다. ]
|
||||
|
||||
|
||||
+ 옵션변경
|
||||
|
||||
* 모드의 변경을 원한다면, types.h파일의 define(__DEF_IINCHIP_BUS__ ) 값을
|
||||
수정하면 원하는 컴파일된다. [생성되는 hex파일명 변경은 makefile에서 가능]
|
||||
|
||||
- 현재 가능 모드
|
||||
1. __DEF_IINCHIP_DIRECT_MODE__
|
||||
2. __DEF_IINCHIP_INDIRECT_MODE__
|
||||
3. __DEF_IINCHIP_SPI_MODE__
|
@ -0,0 +1,111 @@
|
||||
###############################################################################
|
||||
# Makefile for the project EVBs_061114
|
||||
###############################################################################
|
||||
|
||||
## General Flags
|
||||
PROJECT = EVB_W5100_DNS
|
||||
MCU = atmega128
|
||||
TARGET = $(PROJECT)_direct_mode.elf
|
||||
#TARGET = $(PROJECT)_indirect_mode.elf
|
||||
#TARGET = $(PROJECT)_spi_mode.elf
|
||||
CC = avr-gcc.exe
|
||||
|
||||
## Options common to compile, link and assembly rules
|
||||
COMMON = -mmcu=$(MCU)
|
||||
|
||||
## Compile options common for all C compilation units.
|
||||
CFLAGS = $(COMMON)
|
||||
CFLAGS += -Wall -gdwarf-2 -O0 -fsigned-char
|
||||
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d -D__COMPILER_VERSION__=2
|
||||
INCLUDES = -I../mcu -I../iinchip -I../main -I../inet -I../util
|
||||
|
||||
## Assembly specific flags
|
||||
ASMFLAGS = $(COMMON)
|
||||
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
|
||||
|
||||
## Linker flags
|
||||
LDFLAGS = $(COMMON)
|
||||
LDFLAGS +=
|
||||
|
||||
|
||||
## Intel Hex file production flags
|
||||
HEX_FLASH_FLAGS = -R .eeprom
|
||||
|
||||
HEX_EEPROM_FLAGS = -j .eeprom
|
||||
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
|
||||
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0
|
||||
|
||||
|
||||
## Objects that must be built in order to link
|
||||
OBJECTS = md5.o socket.o w5100.o main.o delay.o serial.o mcu.o dns.o sockutil.o util.o
|
||||
|
||||
## Objects explicitly added by the user
|
||||
LINKONLYOBJECTS =
|
||||
|
||||
## Build
|
||||
all: $(TARGET) $(PROJECT)_direct_mode.hex $(PROJECT)_direct_mode.eep size
|
||||
#all: $(TARGET) $(PROJECT)_indirect_mode.hex $(PROJECT)_indirect_mode.eep size
|
||||
#all: $(TARGET) $(PROJECT)_spi_mode.hex $(PROJECT)_spi_mode.eep size
|
||||
|
||||
## Compile
|
||||
delay.o: ../mcu/delay.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
mcu.o: ../mcu/mcu.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
serial.o: ../mcu/serial.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
#timer.o: ../mcu/timer.c
|
||||
# $(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
main.o: ../main/main.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
md5.o: ../iinchip/md5.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
socket.o: ../iinchip/socket.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
w5100.o: ../iinchip/w5100.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
dns.o: ../inet/dns.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
sockutil.o: ../util/sockutil.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
util.o: ../util/util.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
##Link
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
|
||||
|
||||
%.hex: $(TARGET)
|
||||
avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@
|
||||
|
||||
%.eep: $(TARGET)
|
||||
avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@
|
||||
|
||||
%.lss: $(TARGET)
|
||||
avr-objdump -h -S $< > $@
|
||||
|
||||
size: ${TARGET}
|
||||
@echo
|
||||
@avr-size -C --mcu=${MCU} ${TARGET}
|
||||
|
||||
## Clean target
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-rm -rf $(OBJECTS) dep/*
|
||||
-rm -f $(PROJECT)_direct_mode.elf $(PROJECT)_direct_mode.hex $(PROJECT)_direct_mode.eep
|
||||
-rm -f $(PROJECT)_indirect_mode.elf $(PROJECT)_indirect_mode.hex $(PROJECT)_indirect_mode.eep
|
||||
-rm -f $(PROJECT)_spi_mode.elf $(PROJECT)_spi_mode.hex $(PROJECT)_spi_mode.eep
|
||||
|
||||
## Other dependencies
|
||||
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)
|
||||
|
@ -0,0 +1,435 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
#
|
||||
# WinAVR Sample makefile written by Eric B. Weddington, J?rg Wunsch, et al.
|
||||
# Released to the Public Domain
|
||||
# Please read the make user manual!
|
||||
#
|
||||
# Additional material for this makefile was submitted by:
|
||||
# Tim Henigan
|
||||
# Peter Fleury
|
||||
# Reiner Patommel
|
||||
# Sander Pool
|
||||
# Frederik Rouleau
|
||||
# Markus Pfaff
|
||||
#
|
||||
# On command line:
|
||||
#
|
||||
# make all = Make software.
|
||||
#
|
||||
# make clean = Clean out built project files.
|
||||
#
|
||||
# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).
|
||||
#
|
||||
# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio
|
||||
# 4.07 or greater).
|
||||
#
|
||||
# make program = Download the hex file to the device, using avrdude. Please
|
||||
# customize the avrdude settings below first!
|
||||
#
|
||||
# make filename.s = Just compile filename.c into the assembler code only
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#
|
||||
|
||||
|
||||
# MCU name
|
||||
MCU = atmega128
|
||||
|
||||
# Output format. (can be srec, ihex, binary)
|
||||
FORMAT = ihex
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = EVB_W5100_DNS_direct_mode
|
||||
#TARGET = EVB_W5100_DNS_indirect_mode.elf
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = ../main/main.c \
|
||||
../mcu/serial.c ../mcu/mcu.c ../mcu/delay.c \
|
||||
../iinchip/w5100.c ../iinchip/socket.c ../iinchip/md5.c \
|
||||
../util/sockutil.c ../util/util.c ../inet/dns.c
|
||||
|
||||
|
||||
# List Assembler source files here.
|
||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
||||
# will not be considered source files but generated files (assembler
|
||||
# output from the compiler), and will be deleted upon "make clean"!
|
||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
||||
# it will preserve the spelling of the filenames, and gcc itself does
|
||||
# care about how the name is spelled on its command-line.
|
||||
ASRC =
|
||||
|
||||
|
||||
|
||||
# Optimization level, can be [0, 1, 2, 3, s].
|
||||
# 0 = turn off optimization. s = optimize for size.
|
||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
||||
OPT = 0
|
||||
|
||||
# Debugging format.
|
||||
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
|
||||
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
|
||||
DEBUG = stabs
|
||||
|
||||
# List any extra directories to look for include files here.
|
||||
# Each directory must be seperated by a space.
|
||||
EXTRAINCDIRS =
|
||||
|
||||
|
||||
# Compiler flag to set the C Standard level.
|
||||
# c89 - "ANSI" C
|
||||
# gnu89 - c89 plus GCC extensions
|
||||
# c99 - ISO C99 standard (not yet fully implemented)
|
||||
# gnu99 - c99 plus GCC extensions
|
||||
CSTANDARD = -std=gnu99
|
||||
|
||||
# Place -D or -U options here
|
||||
CDEFS =
|
||||
|
||||
# Place -I options here
|
||||
CINCS =
|
||||
|
||||
|
||||
# Compiler flags.
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CFLAGS = -g$(DEBUG)
|
||||
CFLAGS += $(CDEFS) $(CINCS)
|
||||
CFLAGS += -O$(OPT)
|
||||
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
|
||||
CFLAGS += -Wall -Wstrict-prototypes
|
||||
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
|
||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
CFLAGS += $(CSTANDARD)
|
||||
|
||||
INCLUDES = -I../mcu -I../iinchip -I../main -I../inet -I../util
|
||||
|
||||
|
||||
# Assembler flags.
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -ahlms: create listing
|
||||
# -gstabs: have the assembler create line number information; note that
|
||||
# for use in COFF files, additional information about filenames
|
||||
# and function names needs to be present in the assembler source
|
||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
||||
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
||||
|
||||
|
||||
|
||||
#Additional libraries.
|
||||
|
||||
# Minimalistic printf version
|
||||
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
|
||||
|
||||
# Floating point printf version (requires MATH_LIB = -lm below)
|
||||
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
|
||||
|
||||
PRINTF_LIB =
|
||||
|
||||
# Minimalistic scanf version
|
||||
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
|
||||
|
||||
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
|
||||
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
|
||||
|
||||
SCANF_LIB =
|
||||
|
||||
MATH_LIB = -lm
|
||||
|
||||
# External memory options
|
||||
|
||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
||||
# used for variables (.data/.bss) and heap (malloc()).
|
||||
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
|
||||
|
||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
||||
# only used for heap (malloc()).
|
||||
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
|
||||
|
||||
EXTMEMOPTS =
|
||||
|
||||
# Linker flags.
|
||||
# -Wl,...: tell GCC to pass this to linker.
|
||||
# -Map: create map file
|
||||
# --cref: add cross reference to map file
|
||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||
LDFLAGS += $(EXTMEMOPTS)
|
||||
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
|
||||
|
||||
|
||||
|
||||
|
||||
# Programming support using avrdude. Settings and variables.
|
||||
|
||||
# Programming hardware: alf avr910 avrisp bascom bsd
|
||||
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
|
||||
#
|
||||
# Type: avrdude -c ?
|
||||
# to get a full listing.
|
||||
#
|
||||
AVRDUDE_PROGRAMMER = stk500
|
||||
|
||||
# com1 = serial port. Use lpt1 to connect to parallel port.
|
||||
AVRDUDE_PORT = com1 # programmer connected to serial device
|
||||
|
||||
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
||||
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
|
||||
|
||||
|
||||
# Uncomment the following if you want avrdude's erase cycle counter.
|
||||
# Note that this counter needs to be initialized first using -Yn,
|
||||
# see avrdude manual.
|
||||
#AVRDUDE_ERASE_COUNTER = -y
|
||||
|
||||
# Uncomment the following if you do /not/ wish a verification to be
|
||||
# performed after programming the device.
|
||||
#AVRDUDE_NO_VERIFY = -V
|
||||
|
||||
# Increase verbosity level. Please use this when submitting bug
|
||||
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
|
||||
# to submit bug reports.
|
||||
#AVRDUDE_VERBOSE = -v -v
|
||||
|
||||
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Define directories, if needed.
|
||||
DIRAVR = c:/winavr2
|
||||
DIRAVRBIN = $(DIRAVR)/bin
|
||||
DIRAVRUTILS = $(DIRAVR)/utils/bin
|
||||
DIRINC = .
|
||||
DIRLIB = $(DIRAVR)/avr/lib
|
||||
|
||||
|
||||
# Define programs and commands.
|
||||
SHELL = sh
|
||||
CC = avr-gcc
|
||||
OBJCOPY = avr-objcopy
|
||||
OBJDUMP = avr-objdump
|
||||
SIZE = avr-size
|
||||
NM = avr-nm
|
||||
AVRDUDE = avrdude
|
||||
REMOVE = rm -f
|
||||
COPY = cp
|
||||
|
||||
|
||||
|
||||
|
||||
# Define Messages
|
||||
# English
|
||||
MSG_ERRORS_NONE = Errors: none
|
||||
MSG_BEGIN = -------- begin --------
|
||||
MSG_END = -------- end --------
|
||||
MSG_SIZE_BEFORE = Size before:
|
||||
MSG_SIZE_AFTER = Size after:
|
||||
MSG_COFF = Converting to AVR COFF:
|
||||
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
|
||||
MSG_FLASH = Creating load file for Flash:
|
||||
MSG_EEPROM = Creating load file for EEPROM:
|
||||
MSG_EXTENDED_LISTING = Creating Extended Listing:
|
||||
MSG_SYMBOL_TABLE = Creating Symbol Table:
|
||||
MSG_LINKING = Linking:
|
||||
MSG_COMPILING = Compiling:
|
||||
MSG_ASSEMBLING = Assembling:
|
||||
MSG_CLEANING = Cleaning project:
|
||||
|
||||
|
||||
|
||||
|
||||
# Define all object files.
|
||||
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
|
||||
#OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) socket.o md5.o avr_util.o avr_serial.o
|
||||
|
||||
# Define all listing files.
|
||||
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
|
||||
|
||||
|
||||
# Compiler flags to generate dependency files.
|
||||
GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d
|
||||
|
||||
|
||||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
ALL_CFLAGS = -D__COMPILER_VERSION__=0 -mmcu=$(MCU) -I. $(INCLUDES) $(CFLAGS) $(GENDEPFLAGS)
|
||||
ALL_ASFLAGS = -mmcu=$(MCU) -I. $(INCLUDES) -x assembler-with-cpp $(ASFLAGS)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Default target.
|
||||
all: begin gccversion sizebefore build sizeafter finished end
|
||||
|
||||
build: elf hex eep lss sym
|
||||
|
||||
elf: $(TARGET).elf
|
||||
hex: $(TARGET).hex
|
||||
eep: $(TARGET).eep
|
||||
lss: $(TARGET).lss
|
||||
sym: $(TARGET).sym
|
||||
|
||||
|
||||
|
||||
# Eye candy.
|
||||
# AVR Studio 3.x does not check make's exit code but relies on
|
||||
# the following magic strings to be generated by the compile job.
|
||||
begin:
|
||||
@echo
|
||||
@echo $(MSG_BEGIN)
|
||||
|
||||
finished:
|
||||
@echo $(MSG_ERRORS_NONE)
|
||||
|
||||
end:
|
||||
@echo $(MSG_END)
|
||||
@echo
|
||||
|
||||
|
||||
# Display size of file.
|
||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
||||
ELFSIZE = $(SIZE) -A $(TARGET).elf
|
||||
sizebefore:
|
||||
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
|
||||
|
||||
sizeafter:
|
||||
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
|
||||
|
||||
|
||||
|
||||
# Display compiler version information.
|
||||
gccversion :
|
||||
@$(CC) --version
|
||||
|
||||
|
||||
|
||||
# Program the device.
|
||||
program: $(TARGET).hex $(TARGET).eep
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
|
||||
|
||||
|
||||
|
||||
|
||||
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
|
||||
COFFCONVERT=$(OBJCOPY) --debugging \
|
||||
--change-section-address .data-0x800000 \
|
||||
--change-section-address .bss-0x800000 \
|
||||
--change-section-address .noinit-0x800000 \
|
||||
--change-section-address .eeprom-0x810000
|
||||
|
||||
|
||||
coff: $(TARGET).elf
|
||||
@echo
|
||||
@echo $(MSG_COFF) $(TARGET).cof
|
||||
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
|
||||
|
||||
|
||||
extcoff: $(TARGET).elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
|
||||
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
|
||||
|
||||
|
||||
|
||||
# Create final output files (.hex, .eep) from ELF output file.
|
||||
%.hex: %.elf
|
||||
@echo
|
||||
@echo $(MSG_FLASH) $@
|
||||
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
|
||||
|
||||
%.eep: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EEPROM) $@
|
||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
||||
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_LISTING) $@
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
# Create a symbol table from ELF output file.
|
||||
%.sym: %.elf
|
||||
@echo
|
||||
@echo $(MSG_SYMBOL_TABLE) $@
|
||||
$(NM) -n $< > $@
|
||||
|
||||
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
.SECONDARY : $(TARGET).elf
|
||||
.PRECIOUS : $(OBJ)
|
||||
%.elf: $(OBJ)
|
||||
@echo
|
||||
@echo $(MSG_LINKING) $@
|
||||
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
|
||||
|
||||
|
||||
# Compile: create object files from C source files.
|
||||
%.o : %.c
|
||||
@echo
|
||||
@echo $(MSG_COMPILING) $<
|
||||
$(CC) -c $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C source files.
|
||||
%.s : %.c
|
||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Assemble: create object files from assembler source files.
|
||||
%.o : %.S
|
||||
@echo
|
||||
@echo $(MSG_ASSEMBLING) $<
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
||||
|
||||
# Target: clean project.
|
||||
clean: begin clean_list finished end
|
||||
|
||||
clean_list :
|
||||
@echo
|
||||
@echo $(MSG_CLEANING)
|
||||
$(REMOVE) $(TARGET).hex
|
||||
$(REMOVE) $(TARGET).eep
|
||||
$(REMOVE) $(TARGET).obj
|
||||
$(REMOVE) $(TARGET).cof
|
||||
$(REMOVE) $(TARGET).elf
|
||||
$(REMOVE) $(TARGET).map
|
||||
$(REMOVE) $(TARGET).obj
|
||||
$(REMOVE) $(TARGET).a90
|
||||
$(REMOVE) $(TARGET).sym
|
||||
$(REMOVE) $(TARGET).lnk
|
||||
$(REMOVE) $(TARGET).lss
|
||||
$(REMOVE) $(OBJ)
|
||||
$(REMOVE) $(LST)
|
||||
$(REMOVE) $(SRC:.c=.s)
|
||||
$(REMOVE) $(SRC:.c=.d)
|
||||
$(REMOVE) .dep/*
|
||||
|
||||
|
||||
|
||||
|
||||
# Include the dependency files.
|
||||
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
||||
|
||||
|
||||
# Listing of phony targets.
|
||||
.PHONY : all begin finish end sizebefore sizeafter gccversion \
|
||||
build elf hex eep lss sym coff extcoff \
|
||||
clean clean_list program
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,111 @@
|
||||
###############################################################################
|
||||
# Makefile for the project EVBs_061114
|
||||
###############################################################################
|
||||
|
||||
## General Flags
|
||||
PROJECT = EVB_W5100_DNS
|
||||
MCU = atmega128
|
||||
TARGET = $(PROJECT)_direct_mode.elf
|
||||
#TARGET = $(PROJECT)_indirect_mode.elf
|
||||
#TARGET = $(PROJECT)_spi_mode.elf
|
||||
CC = avr-gcc.exe
|
||||
|
||||
## Options common to compile, link and assembly rules
|
||||
COMMON = -mmcu=$(MCU)
|
||||
|
||||
## Compile options common for all C compilation units.
|
||||
CFLAGS = $(COMMON)
|
||||
CFLAGS += -Wall -gdwarf-2 -O0 -fsigned-char
|
||||
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d -D__COMPILER_VERSION__=2
|
||||
INCLUDES = -I../mcu -I../iinchip -I../main -I../inet -I../util
|
||||
|
||||
## Assembly specific flags
|
||||
ASMFLAGS = $(COMMON)
|
||||
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
|
||||
|
||||
## Linker flags
|
||||
LDFLAGS = $(COMMON)
|
||||
LDFLAGS +=
|
||||
|
||||
|
||||
## Intel Hex file production flags
|
||||
HEX_FLASH_FLAGS = -R .eeprom
|
||||
|
||||
HEX_EEPROM_FLAGS = -j .eeprom
|
||||
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
|
||||
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0
|
||||
|
||||
|
||||
## Objects that must be built in order to link
|
||||
OBJECTS = md5.o socket.o w5100.o main.o delay.o serial.o mcu.o dns.o sockutil.o util.o
|
||||
|
||||
## Objects explicitly added by the user
|
||||
LINKONLYOBJECTS =
|
||||
|
||||
## Build
|
||||
all: $(TARGET) $(PROJECT)_direct_mode.hex $(PROJECT)_direct_mode.eep size
|
||||
#all: $(TARGET) $(PROJECT)_indirect_mode.hex $(PROJECT)_indirect_mode.eep size
|
||||
#all: $(TARGET) $(PROJECT)_spi_mode.hex $(PROJECT)_spi_mode.eep size
|
||||
|
||||
## Compile
|
||||
delay.o: ../mcu/delay.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
mcu.o: ../mcu/mcu.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
serial.o: ../mcu/serial.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
#timer.o: ../mcu/timer.c
|
||||
# $(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
main.o: ../main/main.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
md5.o: ../iinchip/md5.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
socket.o: ../iinchip/socket.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
w5100.o: ../iinchip/w5100.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
dns.o: ../inet/dns.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
sockutil.o: ../util/sockutil.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
util.o: ../util/util.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
##Link
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
|
||||
|
||||
%.hex: $(TARGET)
|
||||
avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@
|
||||
|
||||
%.eep: $(TARGET)
|
||||
avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@
|
||||
|
||||
%.lss: $(TARGET)
|
||||
avr-objdump -h -S $< > $@
|
||||
|
||||
size: ${TARGET}
|
||||
@echo
|
||||
@avr-size -C --mcu=${MCU} ${TARGET}
|
||||
|
||||
## Clean target
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-rm -rf $(OBJECTS) dep/*
|
||||
-rm -f $(PROJECT)_direct_mode.elf $(PROJECT)_direct_mode.hex $(PROJECT)_direct_mode.eep
|
||||
-rm -f $(PROJECT)_indirect_mode.elf $(PROJECT)_indirect_mode.hex $(PROJECT)_indirect_mode.eep
|
||||
-rm -f $(PROJECT)_spi_mode.elf $(PROJECT)_spi_mode.hex $(PROJECT)_spi_mode.eep
|
||||
|
||||
## Other dependencies
|
||||
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)
|
||||
|
@ -0,0 +1,282 @@
|
||||
/**
|
||||
@file md5.c
|
||||
@brief support MD5 for PPPoE CHAP mode
|
||||
|
||||
taken from RFC-1321/Appendix A.3
|
||||
MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "md5.h"
|
||||
|
||||
// Constants for Transform routine.
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
|
||||
static void md5_transform (uint32[4], uint8 [64]);
|
||||
static void md5_encode (uint8 *, uint32 *, uint32);
|
||||
static void md5_decode (uint32 *, uint8 *, uint32);
|
||||
|
||||
static uint8 padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0
|
||||
};
|
||||
|
||||
// F, G, H and I are basic md5 functions.
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/**
|
||||
@brief ROTATE_LEFT rotates x left n bits.
|
||||
*/
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
|
||||
uint32 FF(uint32 a, uint32 b, uint32 c, uint32 d, uint32 x, uint32 s, uint32 ac)
|
||||
{
|
||||
a += F (b, c, d) + x + (uint32)(ac);
|
||||
a = ROTATE_LEFT (a, s);
|
||||
a += b;
|
||||
return a;
|
||||
}
|
||||
uint32 GG(uint32 a, uint32 b, uint32 c, uint32 d, uint32 x, uint32 s, uint32 ac)
|
||||
{
|
||||
a += G (b, c, d) + x + (uint32)(ac);
|
||||
a = ROTATE_LEFT (a, s);
|
||||
a += b;
|
||||
return a;
|
||||
}
|
||||
|
||||
uint32 HH(uint32 a, uint32 b, uint32 c, uint32 d, uint32 x, uint32 s, uint32 ac)
|
||||
{
|
||||
a += H (b, c, d) + x + (uint32)(ac);
|
||||
a = ROTATE_LEFT (a, s);
|
||||
a += b;
|
||||
return a;
|
||||
}
|
||||
|
||||
uint32 II(uint32 a, uint32 b, uint32 c, uint32 d, uint32 x, uint32 s, uint32 ac)
|
||||
{
|
||||
a += I (b, c, d) + x + (uint32)(ac);
|
||||
a = ROTATE_LEFT (a, s);
|
||||
a += b;
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief md5 initialization. Begins an md5 operation, writing a new context.
|
||||
*/
|
||||
void md5_init(md5_ctx *context)
|
||||
{
|
||||
context->count[0] = context->count[1] = 0;
|
||||
|
||||
// Load magic initialization constants.
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xefcdab89;
|
||||
context->state[2] = 0x98badcfe;
|
||||
context->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief md5 block update operation. Continues an md5 message-digest operation,
|
||||
processing another message block, and updating the context.
|
||||
*/
|
||||
void md5_update(md5_ctx * context, uint8 *input, uint32 inputLen)
|
||||
{
|
||||
uint32 i, index, partLen;
|
||||
|
||||
// Compute number of bytes mod 64
|
||||
index = (uint32)((context->count[0] >> 3) & 0x3F);
|
||||
|
||||
// Update number of bits
|
||||
if ((context->count[0] += ((uint32)inputLen << 3)) < ((uint32)inputLen << 3))
|
||||
context->count[1]++;
|
||||
context->count[1] += ((uint32)inputLen >> 29);
|
||||
|
||||
partLen = 64 - index;
|
||||
|
||||
// md5_Transform as many times as possible.
|
||||
if (inputLen >= partLen)
|
||||
{
|
||||
memcpy(&context->buffer[index], input, partLen);
|
||||
md5_transform(context->state, context->buffer);
|
||||
|
||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||
md5_transform(context->state, &input[i]);
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
i = 0;
|
||||
|
||||
// Buffer remaining input
|
||||
memcpy(&context->buffer[index], &input[i], inputLen - i);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief md5 finalization. Ends an md5 message-digest operation, writing the
|
||||
message digest and zeroizing the context.
|
||||
*/
|
||||
void md5_final(uint8 digest[16], md5_ctx *context)
|
||||
{
|
||||
uint8 bits[8];
|
||||
uint32 index, padLen;
|
||||
|
||||
// Save number of bits
|
||||
md5_encode(bits, context->count, 8);
|
||||
|
||||
// Pad out to 56 mod 64.
|
||||
index = (uint32)((context->count[0] >> 3) & 0x3f);
|
||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
md5_update(context, padding, padLen);
|
||||
|
||||
// Append length (before padding)
|
||||
md5_update(context, bits, 8);
|
||||
// Store state in digest
|
||||
md5_encode(digest, context->state, 16);
|
||||
|
||||
// Zeroize sensitive information.
|
||||
memset((void*)context,0,sizeof(*context));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief md5 basic transformation. Transforms state based on block.
|
||||
*/
|
||||
static void md5_transform(uint32 state[4], uint8 block[64])
|
||||
{
|
||||
uint32 a = state[0];
|
||||
uint32 b = state[1];
|
||||
uint32 c = state[2];
|
||||
uint32 d = state[3];
|
||||
uint32 x[16];
|
||||
|
||||
md5_decode(x, block, 64);
|
||||
|
||||
// Round 1
|
||||
a = FF(a, b, c, d, x[0], S11, 0xd76aa478); // 1
|
||||
d = FF(d, a, b, c, x[1], S12, 0xe8c7b756); // 2
|
||||
c = FF(c, d, a, b, x[2], S13, 0x242070db); // 3
|
||||
b = FF(b, c, d, a, x[3], S14, 0xc1bdceee); // 4
|
||||
a = FF(a, b, c, d, x[4], S11, 0xf57c0faf); // 5
|
||||
d = FF(d, a, b, c, x[5], S12, 0x4787c62a); // 6
|
||||
c = FF(c, d, a, b, x[6], S13, 0xa8304613); // 7
|
||||
b = FF(b, c, d, a, x[7], S14, 0xfd469501); // 8
|
||||
a = FF(a, b, c, d, x[8], S11, 0x698098d8); // 9
|
||||
d = FF(d, a, b, c, x[9], S12, 0x8b44f7af); // 10
|
||||
c = FF(c, d, a, b, x[10], S13, 0xffff5bb1); // 11
|
||||
b = FF(b, c, d, a, x[11], S14, 0x895cd7be); // 12
|
||||
a = FF(a, b, c, d, x[12], S11, 0x6b901122); // 13
|
||||
d = FF(d, a, b, c, x[13], S12, 0xfd987193); // 14
|
||||
c = FF(c, d, a, b, x[14], S13, 0xa679438e); // 15
|
||||
b = FF(b, c, d, a, x[15], S14, 0x49b40821); // 16
|
||||
|
||||
// Round 2
|
||||
a = GG(a, b, c, d, x[1], S21, 0xf61e2562); // 17
|
||||
d = GG(d, a, b, c, x[6], S22, 0xc040b340); // 18
|
||||
c = GG(c, d, a, b, x[11], S23, 0x265e5a51); // 19
|
||||
b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); // 20
|
||||
a = GG(a, b, c, d, x[5], S21, 0xd62f105d); // 21
|
||||
d = GG(d, a, b, c, x[10], S22, 0x2441453); // 22
|
||||
c = GG(c, d, a, b, x[15], S23, 0xd8a1e681); // 23
|
||||
b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); // 24
|
||||
a = GG(a, b, c, d, x[9], S21, 0x21e1cde6); // 25
|
||||
d = GG(d, a, b, c, x[14], S22, 0xc33707d6); // 26
|
||||
c = GG(c, d, a, b, x[3], S23, 0xf4d50d87); // 27
|
||||
b = GG(b, c, d, a, x[8], S24, 0x455a14ed); // 28
|
||||
a = GG(a, b, c, d, x[13], S21, 0xa9e3e905); // 29
|
||||
d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8); // 30
|
||||
c = GG(c, d, a, b, x[7], S23, 0x676f02d9); // 31
|
||||
b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); // 32
|
||||
|
||||
// Round 3
|
||||
a = HH(a, b, c, d, x[5], S31, 0xfffa3942); // 33
|
||||
d = HH(d, a, b, c, x[8], S32, 0x8771f681); // 34
|
||||
c = HH(c, d, a, b, x[11], S33, 0x6d9d6122); // 35
|
||||
b = HH(b, c, d, a, x[14], S34, 0xfde5380c); // 36
|
||||
a = HH(a, b, c, d, x[1], S31, 0xa4beea44); // 37
|
||||
d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9); // 38
|
||||
c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60); // 39
|
||||
b = HH(b, c, d, a, x[10], S34, 0xbebfbc70); // 40
|
||||
a = HH(a, b, c, d, x[13], S31, 0x289b7ec6); // 41
|
||||
d = HH(d, a, b, c, x[0], S32, 0xeaa127fa); // 42
|
||||
c = HH(c, d, a, b, x[3], S33, 0xd4ef3085); // 43
|
||||
b = HH(b, c, d, a, x[6], S34, 0x4881d05); // 44
|
||||
a = HH(a, b, c, d, x[9], S31, 0xd9d4d039); // 45
|
||||
d = HH(d, a, b, c, x[12], S32, 0xe6db99e5); // 46
|
||||
c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8); // 47
|
||||
b = HH(b, c, d, a, x[2], S34, 0xc4ac5665); // 48
|
||||
|
||||
// Round 4
|
||||
a = II(a, b, c, d, x[0], S41, 0xf4292244); // 49
|
||||
d = II(d, a, b, c, x[7], S42, 0x432aff97); // 50
|
||||
c = II(c, d, a, b, x[14], S43, 0xab9423a7); // 51
|
||||
b = II(b, c, d, a, x[5], S44, 0xfc93a039); // 52
|
||||
a = II(a, b, c, d, x[12], S41, 0x655b59c3); // 53
|
||||
d = II(d, a, b, c, x[3], S42, 0x8f0ccc92); // 54
|
||||
c = II(c, d, a, b, x[10], S43, 0xffeff47d); // 55
|
||||
b = II(b, c, d, a, x[1], S44, 0x85845dd1); // 56
|
||||
a = II(a, b, c, d, x[8], S41, 0x6fa87e4f); // 57
|
||||
d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0); // 58
|
||||
c = II(c, d, a, b, x[6], S43, 0xa3014314); // 59
|
||||
b = II(b, c, d, a, x[13], S44, 0x4e0811a1); // 60
|
||||
a = II(a, b, c, d, x[4], S41, 0xf7537e82); // 61
|
||||
d = II(d, a, b, c, x[11], S42, 0xbd3af235); // 62
|
||||
c = II(c, d, a, b, x[2], S43, 0x2ad7d2bb); // 63
|
||||
b = II(b, c, d, a, x[9], S44, 0xeb86d391); // 64
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
// Zeroize sensitive information.
|
||||
memset(&x,0,sizeof(x));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Encodes input (uint32) into output (uint8). Assumes len is a multiple of 4.
|
||||
*/
|
||||
static void md5_encode(uint8 *output, uint32 *input, uint32 len)
|
||||
{
|
||||
uint32 i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
{
|
||||
output[j] = (uint8)(input[i] & 0xff);
|
||||
output[j + 1] = (uint8)((input[i] >> 8) & 0xff);
|
||||
output[j + 2] = (uint8)((input[i] >> 16) & 0xff);
|
||||
output[j + 3] = (uint8)((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Decodes input (uint8) into output (uint32). Assumes len is a multiple of 4.
|
||||
*/
|
||||
static void md5_decode(uint32 *output, uint8 *input, uint32 len)
|
||||
{
|
||||
uint32 i, j;
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((uint32) input[j]) | (((uint32) input[j + 1]) << 8) |
|
||||
(((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24);
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
/**
|
||||
@file md5.h
|
||||
*/
|
||||
|
||||
#ifndef __MD5_H
|
||||
#define __MD5_H
|
||||
|
||||
|
||||
/**
|
||||
@brief MD5 context.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32 state[4]; /**< state (ABCD) */
|
||||
uint32 count[2]; /**< number of bits, modulo 2^64 (lsb first) */
|
||||
uint8 buffer[64]; /**< input buffer */
|
||||
} md5_ctx;
|
||||
|
||||
extern void md5_init(md5_ctx *context);
|
||||
extern void md5_update(md5_ctx *context, uint8 *buffer, uint32 length);
|
||||
extern void md5_final(uint8 result[16], md5_ctx *context);
|
||||
|
||||
#endif // __md5_H
|
@ -0,0 +1,484 @@
|
||||
/*
|
||||
*
|
||||
@file socket.c
|
||||
@brief setting chip register for socket
|
||||
*
|
||||
*/
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "w5100.h"
|
||||
#include "socket.h"
|
||||
|
||||
static uint16 local_port;
|
||||
|
||||
|
||||
/**
|
||||
@brief This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it.
|
||||
@return 1 for sucess else 0.
|
||||
*/
|
||||
uint8 socket(
|
||||
SOCKET s, /**< for socket number */
|
||||
uint8 protocol, /**< for socket protocol */
|
||||
uint16 port, /**< the source port for the socket */
|
||||
uint8 flag /**< the option for the socket */
|
||||
)
|
||||
{
|
||||
uint8 ret;
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("socket()\r\n");
|
||||
#endif
|
||||
if ((protocol == Sn_MR_TCP) || (protocol == Sn_MR_UDP) || (protocol == Sn_MR_IPRAW) || (protocol == Sn_MR_MACRAW) || (protocol == Sn_MR_PPPOE))
|
||||
{
|
||||
close(s);
|
||||
IINCHIP_WRITE(Sn_MR(s),protocol | flag);
|
||||
if (port != 0) {
|
||||
IINCHIP_WRITE(Sn_PORT0(s),(uint8)((port & 0xff00) >> 8));
|
||||
IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(port & 0x00ff));
|
||||
} else {
|
||||
local_port++; // if don't set the source port, set local_port number.
|
||||
IINCHIP_WRITE(Sn_PORT0(s),(uint8)((local_port & 0xff00) >> 8));
|
||||
IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(local_port & 0x00ff));
|
||||
}
|
||||
IINCHIP_WRITE(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("Sn_SR = %.2x , Protocol = %.2x\r\n", IINCHIP_READ(Sn_SR(s)), IINCHIP_READ(Sn_MR(s)));
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief This function close the socket and parameter is "s" which represent the socket number
|
||||
*/
|
||||
void close(SOCKET s)
|
||||
{
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("close()\r\n");
|
||||
#endif
|
||||
IINCHIP_WRITE(Sn_CR(s),Sn_CR_CLOSE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief This function established the connection for the channel in passive (server) mode. This function waits for the request from the peer.
|
||||
@return 1 for success else 0.
|
||||
*/
|
||||
uint8 listen(
|
||||
SOCKET s /**< the socket number */
|
||||
)
|
||||
{
|
||||
uint8 ret;
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("listen()\r\n");
|
||||
#endif
|
||||
if (IINCHIP_READ(Sn_SR(s)) == SOCK_INIT)
|
||||
{
|
||||
IINCHIP_WRITE(Sn_CR(s),Sn_CR_LISTEN);
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("Fail[invalid ip,port]\r\n");
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief This function established the connection for the channel in Active (client) mode.
|
||||
This function waits for the untill the connection is established.
|
||||
|
||||
@return 1 for success else 0.
|
||||
*/
|
||||
uint8 connect(SOCKET s, uint8 * addr, uint16 port)
|
||||
{
|
||||
uint8 ret;
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("connect()\r\n");
|
||||
#endif
|
||||
if
|
||||
(
|
||||
((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
|
||||
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
|
||||
(port == 0x00)
|
||||
)
|
||||
{
|
||||
ret = 0;
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("Fail[invalid ip,port]\r\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
ret = 1;
|
||||
// set destination IP
|
||||
IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
|
||||
IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
|
||||
IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
|
||||
IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
|
||||
IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
|
||||
IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
|
||||
IINCHIP_WRITE(Sn_CR(s),Sn_CR_CONNECT);
|
||||
// wait for completion
|
||||
while (IINCHIP_READ(Sn_CR(s)))
|
||||
{
|
||||
if (IINCHIP_READ(Sn_SR(s)) == SOCK_CLOSED)
|
||||
{
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("SOCK_CLOSED.\r\n");
|
||||
#endif
|
||||
ret = 0; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@brief This function used for disconnect the socket and parameter is "s" which represent the socket number
|
||||
@return 1 for success else 0.
|
||||
*/
|
||||
void disconnect(SOCKET s)
|
||||
{
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("disconnect()\r\n");
|
||||
#endif
|
||||
IINCHIP_WRITE(Sn_CR(s),Sn_CR_DISCON);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief This function used to send the data in TCP mode
|
||||
@return 1 for success else 0.
|
||||
*/
|
||||
uint16 send(
|
||||
SOCKET s, /**< the socket index */
|
||||
const uint8 * buf, /**< a pointer to data */
|
||||
uint16 len /**< the data size to be send */
|
||||
)
|
||||
{
|
||||
uint8 status=0;
|
||||
uint16 ret=0;
|
||||
uint16 freesize=0;
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("send()\r\n");
|
||||
#endif
|
||||
|
||||
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
|
||||
else ret = len;
|
||||
|
||||
// if freebuf is available, start.
|
||||
do
|
||||
{
|
||||
freesize = getSn_TX_FSR(s);
|
||||
status = IINCHIP_READ(Sn_SR(s));
|
||||
if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT))
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("socket %d freesize(%d) empty or error\r\n", s, freesize);
|
||||
#endif
|
||||
} while (freesize < ret);
|
||||
|
||||
// copy data
|
||||
send_data_processing(s, (uint8 *)buf, ret);
|
||||
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
|
||||
|
||||
// wait for completion
|
||||
while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
|
||||
{
|
||||
status = IINCHIP_READ(Sn_SR(s));
|
||||
if (status == SOCK_CLOSED)
|
||||
{
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("SOCK_CLOSED.\r\n");
|
||||
#endif
|
||||
putISR(s, getISR(s) & (Sn_IR_RECV | Sn_IR_DISCON | Sn_IR_CON));
|
||||
IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
|
||||
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief This function is an application I/F function which is used to receive the data in TCP mode.
|
||||
It continues to wait for data as much as the application wants to receive.
|
||||
|
||||
@return received data size for success else -1.
|
||||
*/
|
||||
uint16 recv(
|
||||
SOCKET s, /**< socket index */
|
||||
uint8 * buf, /**< a pointer to copy the data to be received */
|
||||
uint16 len /**< the data size to be read */
|
||||
)
|
||||
{
|
||||
uint16 ret=0;
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("recv()\r\n");
|
||||
#endif
|
||||
|
||||
|
||||
if ( len > 0 )
|
||||
{
|
||||
recv_data_processing(s, buf, len);
|
||||
IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
|
||||
ret = len;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief This function is an application I/F function which is used to send the data for other then TCP mode.
|
||||
Unlike TCP transmission, The peer's destination address and the port is needed.
|
||||
|
||||
@return This function return send data size for success else -1.
|
||||
*/
|
||||
uint16 sendto(
|
||||
SOCKET s, /**< socket index */
|
||||
const uint8 * buf, /**< a pointer to the data */
|
||||
uint16 len, /**< the data size to send */
|
||||
uint8 * addr, /**< the peer's Destination IP address */
|
||||
uint16 port /**< the peer's destination port number */
|
||||
)
|
||||
{
|
||||
uint8 status=0;
|
||||
uint8 isr=0;
|
||||
uint16 ret=0;
|
||||
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("sendto()\r\n");
|
||||
#endif
|
||||
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
|
||||
else ret = len;
|
||||
|
||||
if
|
||||
(
|
||||
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
|
||||
((port == 0x00)) ||(ret == 0)
|
||||
)
|
||||
{
|
||||
;
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("%d Fail[%.2x.%.2x.%.2x.%.2x, %.d, %d]\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len);
|
||||
printf("Fail[invalid ip,port]\r\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
|
||||
IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
|
||||
IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
|
||||
IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
|
||||
IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
|
||||
IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
|
||||
|
||||
// copy data
|
||||
send_data_processing(s, (uint8 *)buf, ret);
|
||||
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
|
||||
|
||||
while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
|
||||
{
|
||||
status = IINCHIP_READ(Sn_SR(s));
|
||||
#ifndef __DEF_IINCHIP_INT__
|
||||
isr = IINCHIP_READ(Sn_IR(s));
|
||||
#endif
|
||||
if ((isr & Sn_IR_TIMEOUT) || (getISR(s) & Sn_IR_TIMEOUT))
|
||||
{
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("send fail.\r\n");
|
||||
#endif
|
||||
putISR(s, getISR(s) & (Sn_IR_RECV | Sn_IR_DISCON | Sn_IR_CON)); /* clear SEND_OK & TIMEOUT in I_STATUS[s] */
|
||||
IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT)); // clear SEND_OK & TIMEOUT in Sn_IR(s)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
|
||||
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief This function is an application I/F function which is used to receive the data in other then
|
||||
TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well.
|
||||
|
||||
@return This function return received data size for success else -1.
|
||||
*/
|
||||
uint16 recvfrom(
|
||||
SOCKET s, /**< the socket number */
|
||||
uint8 * buf, /**< a pointer to copy the data to be received */
|
||||
uint16 len, /**< the data size to read */
|
||||
uint8 * addr, /**< a pointer to store the peer's IP address */
|
||||
uint16 *port /**< a pointer to store the peer's port number. */
|
||||
)
|
||||
{
|
||||
uint8 head[8];
|
||||
uint16 data_len=0;
|
||||
uint16 ptr=0;
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("recvfrom()\r\n");
|
||||
#endif
|
||||
|
||||
if ( len > 0 )
|
||||
{
|
||||
ptr = IINCHIP_READ(Sn_RX_RD0(s));
|
||||
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("ISR_RX: rd_ptr : %.4x\r\n", ptr);
|
||||
#endif
|
||||
switch (IINCHIP_READ(Sn_MR(s)) & 0x07)
|
||||
{
|
||||
case Sn_MR_UDP :
|
||||
read_data(s, (uint8 *)ptr, head, 0x08);
|
||||
ptr += 8;
|
||||
// read peer's IP address, port number.
|
||||
addr[0] = head[0];
|
||||
addr[1] = head[1];
|
||||
addr[2] = head[2];
|
||||
addr[3] = head[3];
|
||||
*port = head[4];
|
||||
*port = (*port << 8) + head[5];
|
||||
data_len = head[6];
|
||||
data_len = (data_len << 8) + head[7];
|
||||
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("UDP msg arrived\r\n");
|
||||
printf("source Port : %d\r\n", *port);
|
||||
printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
|
||||
#endif
|
||||
|
||||
read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
|
||||
ptr += data_len;
|
||||
|
||||
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
|
||||
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
|
||||
break;
|
||||
|
||||
case Sn_MR_IPRAW :
|
||||
read_data(s, (uint8 *)ptr, head, 0x06);
|
||||
ptr += 6;
|
||||
|
||||
addr[0] = head[0];
|
||||
addr[1] = head[1];
|
||||
addr[2] = head[2];
|
||||
addr[3] = head[3];
|
||||
data_len = head[4];
|
||||
data_len = (data_len << 8) + head[5];
|
||||
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("IP RAW msg arrived\r\n");
|
||||
printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
|
||||
#endif
|
||||
read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
|
||||
ptr += data_len;
|
||||
|
||||
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
|
||||
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
|
||||
break;
|
||||
case Sn_MR_MACRAW :
|
||||
read_data(s,(uint8*)ptr,head,2);
|
||||
ptr+=2;
|
||||
data_len = head[0];
|
||||
data_len = (data_len<<8) + head[1] - 2;
|
||||
|
||||
read_data(s,(uint8*) ptr,buf,data_len);
|
||||
ptr += data_len;
|
||||
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
|
||||
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
|
||||
|
||||
#ifdef __DEF_IINCHIP_DGB__
|
||||
printf("MAC RAW msg arrived\r\n");
|
||||
printf("dest mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
|
||||
printf("src mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]);
|
||||
printf("type =%.2X%.2X\r\n",buf[12],buf[13]);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
|
||||
}
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("recvfrom() end ..\r\n");
|
||||
#endif
|
||||
return data_len;
|
||||
}
|
||||
|
||||
|
||||
uint16 igmpsend(SOCKET s, const uint8 * buf, uint16 len)
|
||||
{
|
||||
//uint8 status=0;
|
||||
uint8 isr=0;
|
||||
uint16 ret=0;
|
||||
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("igmpsend()\r\n");
|
||||
#endif
|
||||
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
|
||||
else ret = len;
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
;
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
//printf("%d Fail[%d]\r\n",len);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy data
|
||||
send_data_processing(s, (uint8 *)buf, ret);
|
||||
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
|
||||
|
||||
while (IINCHIP_READ(Sn_CR(s)))
|
||||
{
|
||||
// status = IINCHIP_READ(Sn_SR(s));
|
||||
#ifndef __DEF_IINCHIP_INT__
|
||||
isr = IINCHIP_READ(Sn_IR(s));
|
||||
#endif
|
||||
if ((getISR(s) & Sn_IR_TIMEOUT) || (isr & Sn_IR_TIMEOUT))
|
||||
{
|
||||
#ifdef __DEF_IINCHIP_DBG__
|
||||
printf("igmpsend fail.\r\n");
|
||||
#endif
|
||||
putISR(s, getISR(s) & (Sn_IR_RECV | Sn_IR_DISCON | Sn_IR_CON));
|
||||
IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
|
||||
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
|
||||
}
|
||||
return ret;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
*
|
||||
@file socket.h
|
||||
@brief define function of socket API
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SOCKET_H_
|
||||
#define _SOCKET_H_
|
||||
|
||||
extern uint8 socket(SOCKET s, uint8 protocol, uint16 port, uint8 flag); // Opens a socket(TCP or UDP or IP_RAW mode)
|
||||
extern void close(SOCKET s); // Close socket
|
||||
extern uint8 connect(SOCKET s, uint8 * addr, uint16 port); // Establish TCP connection (Active connection)
|
||||
extern void disconnect(SOCKET s); // disconnect the connection
|
||||
extern uint8 listen(SOCKET s); // Establish TCP connection (Passive connection)
|
||||
extern uint16 send(SOCKET s, const uint8 * buf, uint16 len); // Send data (TCP)
|
||||
extern uint16 recv(SOCKET s, uint8 * buf, uint16 len); // Receive data (TCP)
|
||||
extern uint16 sendto(SOCKET s, const uint8 * buf, uint16 len, uint8 * addr, uint16 port); // Send data (UDP/IP RAW)
|
||||
extern uint16 recvfrom(SOCKET s, uint8 * buf, uint16 len, uint8 * addr, uint16 *port); // Receive data (UDP/IP RAW)
|
||||
|
||||
extern uint16 igmpsend(SOCKET s, const uint8 * buf, uint16 len);
|
||||
#endif
|
||||
/* _SOCKET_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,303 @@
|
||||
/*
|
||||
@file w5100.h
|
||||
*/
|
||||
|
||||
#ifndef _W5100_H_
|
||||
#define _W5100_H_
|
||||
|
||||
|
||||
#define MR __DEF_IINCHIP_MAP_BASE__
|
||||
#define IDM_OR ((__DEF_IINCHIP_MAP_BASE__ + 0x00))
|
||||
#define IDM_AR0 ((__DEF_IINCHIP_MAP_BASE__ + 0x01))
|
||||
#define IDM_AR1 ((__DEF_IINCHIP_MAP_BASE__ + 0x02))
|
||||
#define IDM_DR ((__DEF_IINCHIP_MAP_BASE__ + 0x03))
|
||||
|
||||
|
||||
/**
|
||||
@brief Gateway IP Register address
|
||||
*/
|
||||
#define GAR0 (COMMON_BASE + 0x0001)
|
||||
/**
|
||||
@brief Subnet mask Register address
|
||||
*/
|
||||
#define SUBR0 (COMMON_BASE + 0x0005)
|
||||
/**
|
||||
@brief Source MAC Register address
|
||||
*/
|
||||
#define SHAR0 (COMMON_BASE + 0x0009)
|
||||
/**
|
||||
@brief Source IP Register address
|
||||
*/
|
||||
#define SIPR0 (COMMON_BASE + 0x000F)
|
||||
/**
|
||||
@brief Interrupt Register
|
||||
*/
|
||||
#define IR (COMMON_BASE + 0x0015)
|
||||
/**
|
||||
@brief Interrupt mask register
|
||||
*/
|
||||
#define IMR (COMMON_BASE + 0x0016)
|
||||
/**
|
||||
@brief Timeout register address( 1 is 100us )
|
||||
*/
|
||||
#define RTR0 (COMMON_BASE + 0x0017)
|
||||
/**
|
||||
@brief Retry count reigster
|
||||
*/
|
||||
#define RCR (COMMON_BASE + 0x0019)
|
||||
/**
|
||||
@brief Receive memory size reigster
|
||||
*/
|
||||
#define RMSR (COMMON_BASE + 0x001A)
|
||||
/**
|
||||
@brief Transmit memory size reigster
|
||||
*/
|
||||
#define TMSR (COMMON_BASE + 0x001B)
|
||||
/**
|
||||
@brief Authentication type register address in PPPoE mode
|
||||
*/
|
||||
#define PATR0 (COMMON_BASE + 0x001C)
|
||||
//#define PPPALGO (COMMON_BASE + 0x001D)
|
||||
#define PTIMER (COMMON_BASE + 0x0028)
|
||||
#define PMAGIC (COMMON_BASE + 0x0029)
|
||||
|
||||
/**
|
||||
@brief Unreachable IP register address in UDP mode
|
||||
*/
|
||||
#define UIPR0 (COMMON_BASE + 0x002A)
|
||||
/**
|
||||
@brief Unreachable Port register address in UDP mode
|
||||
*/
|
||||
#define UPORT0 (COMMON_BASE + 0x002E)
|
||||
|
||||
/**
|
||||
@brief socket register
|
||||
*/
|
||||
#define CH_BASE (COMMON_BASE + 0x0400)
|
||||
/**
|
||||
@brief size of each channel register map
|
||||
*/
|
||||
#define CH_SIZE 0x0100
|
||||
/**
|
||||
@brief socket Mode register
|
||||
*/
|
||||
#define Sn_MR(ch) (CH_BASE + ch * CH_SIZE + 0x0000)
|
||||
/**
|
||||
@brief channel Sn_CR register
|
||||
*/
|
||||
#define Sn_CR(ch) (CH_BASE + ch * CH_SIZE + 0x0001)
|
||||
/**
|
||||
@brief channel interrupt register
|
||||
*/
|
||||
#define Sn_IR(ch) (CH_BASE + ch * CH_SIZE + 0x0002)
|
||||
/**
|
||||
@brief channel status register
|
||||
*/
|
||||
#define Sn_SR(ch) (CH_BASE + ch * CH_SIZE + 0x0003)
|
||||
/**
|
||||
@brief source port register
|
||||
*/
|
||||
#define Sn_PORT0(ch) (CH_BASE + ch * CH_SIZE + 0x0004)
|
||||
/**
|
||||
@brief Peer MAC register address
|
||||
*/
|
||||
#define Sn_DHAR0(ch) (CH_BASE + ch * CH_SIZE + 0x0006)
|
||||
/**
|
||||
@brief Peer IP register address
|
||||
*/
|
||||
#define Sn_DIPR0(ch) (CH_BASE + ch * CH_SIZE + 0x000C)
|
||||
/**
|
||||
@brief Peer port register address
|
||||
*/
|
||||
#define Sn_DPORT0(ch) (CH_BASE + ch * CH_SIZE + 0x0010)
|
||||
/**
|
||||
@brief Maximum Segment Size(Sn_MSSR0) register address
|
||||
*/
|
||||
#define Sn_MSSR0(ch) (CH_BASE + ch * CH_SIZE + 0x0012)
|
||||
/**
|
||||
@brief Protocol of IP Header field register in IP raw mode
|
||||
*/
|
||||
#define Sn_PROTO(ch) (CH_BASE + ch * CH_SIZE + 0x0014)
|
||||
|
||||
/**
|
||||
@brief IP Type of Service(TOS) Register
|
||||
*/
|
||||
#define Sn_TOS(ch) (CH_BASE + ch * CH_SIZE + 0x0015)
|
||||
/**
|
||||
@brief IP Time to live(TTL) Register
|
||||
*/
|
||||
#define Sn_TTL(ch) (CH_BASE + ch * CH_SIZE + 0x0016)
|
||||
|
||||
//not support
|
||||
//#define RX_CH_DMEM_SIZE (COMMON_BASE + 0x001E)
|
||||
//#define TX_CH_DMEM_SIZE (COMMON_BASE + 0x001F)
|
||||
|
||||
/**
|
||||
@brief Transmit free memory size register
|
||||
*/
|
||||
#define Sn_TX_FSR0(ch) (CH_BASE + ch * CH_SIZE + 0x0020)
|
||||
/**
|
||||
@brief Transmit memory read pointer register address
|
||||
*/
|
||||
#define Sn_TX_RD0(ch) (CH_BASE + ch * CH_SIZE + 0x0022)
|
||||
/**
|
||||
@brief Transmit memory write pointer register address
|
||||
*/
|
||||
#define Sn_TX_WR0(ch) (CH_BASE + ch * CH_SIZE + 0x0024)
|
||||
/**
|
||||
@brief Received data size register
|
||||
*/
|
||||
#define Sn_RX_RSR0(ch) (CH_BASE + ch * CH_SIZE + 0x0026)
|
||||
/**
|
||||
@brief Read point of Receive memory
|
||||
*/
|
||||
#define Sn_RX_RD0(ch) (CH_BASE + ch * CH_SIZE + 0x0028)
|
||||
/**
|
||||
@brief Write point of Receive memory
|
||||
*/
|
||||
#define Sn_RX_WR0(ch) (CH_BASE + ch * CH_SIZE + 0x002A)
|
||||
|
||||
|
||||
|
||||
/* MODE register values */
|
||||
#define MR_RST 0x80 /**< reset */
|
||||
#define MR_PB 0x10 /**< ping block */
|
||||
#define MR_PPPOE 0x08 /**< enable pppoe */
|
||||
#define MR_LB 0x04 /**< little or big endian selector in indirect mode */
|
||||
#define MR_AI 0x02 /**< auto-increment in indirect mode */
|
||||
#define MR_IND 0x01 /**< enable indirect mode */
|
||||
|
||||
/* IR register values */
|
||||
#define IR_CONFLICT 0x80 /**< check ip confict */
|
||||
#define IR_UNREACH 0x40 /**< get the destination unreachable message in UDP sending */
|
||||
#define IR_PPPoE 0x20 /**< get the PPPoE close message */
|
||||
#define IR_SOCK(ch) (0x01 << ch) /**< check socket interrupt */
|
||||
|
||||
/* Sn_MR values */
|
||||
#define Sn_MR_CLOSE 0x00 /**< unused socket */
|
||||
#define Sn_MR_TCP 0x01 /**< TCP */
|
||||
#define Sn_MR_UDP 0x02 /**< UDP */
|
||||
#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */
|
||||
#define Sn_MR_MACRAW 0x04 /**< MAC LAYER RAW SOCK */
|
||||
#define Sn_MR_PPPOE 0x05 /**< PPPoE */
|
||||
#define Sn_MR_ND 0x20 /**< No Delayed Ack(TCP) flag */
|
||||
#define Sn_MR_MULTI 0x80 /**< support multicating */
|
||||
|
||||
|
||||
/* Sn_CR values */
|
||||
#define Sn_CR_OPEN 0x01 /**< initialize or open socket */
|
||||
#define Sn_CR_LISTEN 0x02 /**< wait connection request in tcp mode(Server mode) */
|
||||
#define Sn_CR_CONNECT 0x04 /**< send connection request in tcp mode(Client mode) */
|
||||
#define Sn_CR_DISCON 0x08 /**< send closing reqeuset in tcp mode */
|
||||
#define Sn_CR_CLOSE 0x10 /**< close socket */
|
||||
#define Sn_CR_SEND 0x20 /**< updata txbuf pointer, send data */
|
||||
#define Sn_CR_SEND_MAC 0x21 /**< send data with MAC address, so without ARP process */
|
||||
#define Sn_CR_SEND_KEEP 0x22 /**< send keep alive message */
|
||||
#define Sn_CR_RECV 0x40 /**< update rxbuf pointer, recv data */
|
||||
|
||||
#ifdef __DEF_IINCHIP_PPP__
|
||||
#define Sn_CR_PCON 0x23
|
||||
#define Sn_CR_PDISCON 0x24
|
||||
#define Sn_CR_PCR 0x25
|
||||
#define Sn_CR_PCN 0x26
|
||||
#define Sn_CR_PCJ 0x27
|
||||
#endif
|
||||
|
||||
/* Sn_IR values */
|
||||
#ifdef __DEF_IINCHIP_PPP__
|
||||
#define Sn_IR_PRECV 0x80
|
||||
#define Sn_IR_PFAIL 0x40
|
||||
#define Sn_IR_PNEXT 0x20
|
||||
#endif
|
||||
#define Sn_IR_SEND_OK 0x10 /**< complete sending */
|
||||
#define Sn_IR_TIMEOUT 0x08 /**< assert timeout */
|
||||
#define Sn_IR_RECV 0x04 /**< receiving data */
|
||||
#define Sn_IR_DISCON 0x02 /**< closed socket */
|
||||
#define Sn_IR_CON 0x01 /**< established connection */
|
||||
|
||||
/* Sn_SR values */
|
||||
#define SOCK_CLOSED 0x00 /**< closed */
|
||||
#define SOCK_INIT 0x13 /**< init state */
|
||||
#define SOCK_LISTEN 0x14 /**< listen state */
|
||||
#define SOCK_SYNSENT 0x15 /**< connection state */
|
||||
#define SOCK_SYNRECV 0x16 /**< connection state */
|
||||
#define SOCK_ESTABLISHED 0x17 /**< success to connect */
|
||||
#define SOCK_FIN_WAIT 0x18 /**< closing state */
|
||||
#define SOCK_CLOSING 0x1A /**< closing state */
|
||||
#define SOCK_TIME_WAIT 0x1B /**< closing state */
|
||||
#define SOCK_CLOSE_WAIT 0x1C /**< closing state */
|
||||
#define SOCK_LAST_ACK 0x1D /**< closing state */
|
||||
#define SOCK_UDP 0x22 /**< udp socket */
|
||||
#define SOCK_IPRAW 0x32 /**< ip raw mode socket */
|
||||
#define SOCK_MACRAW 0x42 /**< mac raw mode socket */
|
||||
#define SOCK_PPPOE 0x5F /**< pppoe socket */
|
||||
|
||||
/* IP PROTOCOL */
|
||||
#define IPPROTO_IP 0 /**< Dummy for IP */
|
||||
#define IPPROTO_ICMP 1 /**< Control message protocol */
|
||||
#define IPPROTO_IGMP 2 /**< Internet group management protocol */
|
||||
#define IPPROTO_GGP 3 /**< Gateway^2 (deprecated) */
|
||||
#define IPPROTO_TCP 6 /**< TCP */
|
||||
#define IPPROTO_PUP 12 /**< PUP */
|
||||
#define IPPROTO_UDP 17 /**< UDP */
|
||||
#define IPPROTO_IDP 22 /**< XNS idp */
|
||||
#define IPPROTO_ND 77 /**< UNOFFICIAL net disk protocol */
|
||||
#define IPPROTO_RAW 255 /**< Raw IP packet */
|
||||
|
||||
|
||||
/*********************************************************
|
||||
* iinchip access function
|
||||
*********************************************************/
|
||||
extern uint8 IINCHIP_READ(uint16 addr);
|
||||
extern uint8 IINCHIP_WRITE(uint16 addr,uint8 data);
|
||||
extern uint16 wiz_read_buf(uint16 addr, uint8* buf,uint16 len);
|
||||
extern uint16 wiz_write_buf(uint16 addr,uint8* buf,uint16 len);
|
||||
|
||||
extern void iinchip_init(void); // reset iinchip
|
||||
extern void sysinit(uint8 tx_size, uint8 rx_size); // setting tx/rx buf size
|
||||
extern uint8 getISR(uint8 s);
|
||||
extern void putISR(uint8 s, uint8 val);
|
||||
extern uint16 getIINCHIP_RxMAX(uint8 s);
|
||||
extern uint16 getIINCHIP_TxMAX(uint8 s);
|
||||
extern uint16 getIINCHIP_RxMASK(uint8 s);
|
||||
extern uint16 getIINCHIP_TxMASK(uint8 s);
|
||||
extern uint16 getIINCHIP_RxBASE(uint8 s);
|
||||
extern uint16 getIINCHIP_TxBASE(uint8 s);
|
||||
extern void setGAR(uint8 * addr); // set gateway address
|
||||
extern void setSUBR(uint8 * addr); // set subnet mask address
|
||||
extern void setSHAR(uint8 * addr); // set local MAC address
|
||||
extern void setSIPR(uint8 * addr); // set local IP address
|
||||
extern void setRTR(uint16 timeout); // set retry duration for data transmission, connection, closing ...
|
||||
extern void setRCR(uint8 retry); // set retry count (above the value, assert timeout interrupt)
|
||||
extern void setIMR(uint8 mask); // set interrupt mask.
|
||||
extern void getGAR(uint8 * addr);
|
||||
extern void getSUBR(uint8 * addr);
|
||||
extern void getSHAR(uint8 * addr);
|
||||
extern void getSIPR(uint8 * addr);
|
||||
extern uint8 getIR( void );
|
||||
extern void setSn_MSS(SOCKET s, uint16 Sn_MSSR0); // set maximum segment size
|
||||
extern void setSn_PROTO(SOCKET s, uint8 proto); // set IP Protocol value using IP-Raw mode
|
||||
extern uint8 getSn_IR(SOCKET s); // get socket interrupt status
|
||||
extern uint8 getSn_SR(SOCKET s); // get socket status
|
||||
extern uint16 getSn_TX_FSR(SOCKET s); // get socket TX free buf size
|
||||
extern uint16 getSn_RX_RSR(SOCKET s); // get socket RX recv buf size
|
||||
extern void setSn_DHAR(SOCKET s, uint8 * addr);
|
||||
extern void setSn_DIPR(SOCKET s, uint8 * addr);
|
||||
extern void setSn_DPORT(SOCKET s, uint8 * addr);
|
||||
extern void getSn_DHAR(SOCKET s, uint8 * addr);
|
||||
extern void getSn_DIPR(SOCKET s, uint8 * addr);
|
||||
extern void getSn_DPORT(SOCKET s, uint8 * addr);
|
||||
extern void setSn_TTL(SOCKET s, uint8 ttl);
|
||||
extern void setMR(uint8 val);
|
||||
|
||||
#ifdef __DEF_IINCHIP_PPP__
|
||||
extern uint8 pppinit(uint8 *id, uint8 idlen, uint8 *passwd, uint8 passwdlen);
|
||||
extern uint8 pppterm(uint8 *mac,uint8 *sessionid);
|
||||
#endif
|
||||
|
||||
extern void send_data_processing(SOCKET s, uint8 *data, uint16 len);
|
||||
extern void recv_data_processing(SOCKET s, uint8 *data, uint16 len);
|
||||
extern void read_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len);
|
||||
extern void write_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len);
|
||||
|
||||
#endif
|
@ -0,0 +1,607 @@
|
||||
/**
|
||||
@file dns.c
|
||||
@brief Realize Simple Domain Name System Protocol \n
|
||||
Detail DNS protocol refer to RFC 1034
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "delay.h"
|
||||
#include "socket.h"
|
||||
#include "myprintf.h"
|
||||
#include "sockutil.h"
|
||||
#include "util.h"
|
||||
//#include "config.h"
|
||||
#include "w5100.h"
|
||||
|
||||
#include "dns.h"
|
||||
|
||||
#define DEBUG_DNS
|
||||
|
||||
|
||||
static u_short dns_id = 0x1122; /**< DNS query id */
|
||||
static u_char* dns_buf;
|
||||
static u_char* get_domain_name;
|
||||
static u_long get_domain_ip; /**< Resolved ip address */
|
||||
static QUERYDATA query_data; /**< Query type */
|
||||
|
||||
//extern NETCONF NetConf;
|
||||
u_long dns_server_ip = 0; /**< instead of "NETCONF" */
|
||||
|
||||
static int dns_makequery(u_char op,char * qname); /* make a DNS query */
|
||||
static int dns_parse_reponse(void); /* analyze a response from DNS sever */
|
||||
|
||||
static u_char * dns_parse_question(u_char * cp); /* analyze a question part in resources recode */
|
||||
static u_char * dns_answer(u_char *cp); /* analyze a answer part in resources recode */
|
||||
static int parse_name(char* cp,char* qname, u_int qname_maxlen); /* analyze a qname in each part. */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@brief Transfer query message for user entered domain name to desiginated DNS Server
|
||||
@return 1 - DNS resolve Success, 0 - DNS resolve Failue
|
||||
*/
|
||||
u_char dns_query(
|
||||
SOCKET s, /**< socket handle */
|
||||
u_long dnsip, /**< DNS server ip address(32bit network ordering address) */
|
||||
u_char * domain_name, /**< if querydata value is BYNAME then use parameter for resolving domain ip \n
|
||||
BYIP then use return value(resolved domain name from DNS) */
|
||||
u_long* domain_ip, /**< if querydata value is BYNAME then use return value(resolved domain ip from DNS) \n
|
||||
BYIP then use parameter for resolving domain name */
|
||||
QUERYDATA querydata, /**< BYNAME : use domain_name for resolving domain_ip \n
|
||||
BYIP : use domain_ip for resolving domain_name */
|
||||
u_int elapse /**< wait for resopnse from DNS server (unit : 10ms) */
|
||||
)
|
||||
{
|
||||
int len;
|
||||
u_int port;
|
||||
u_char reponse_received = 0;
|
||||
u_char* qname = 0;
|
||||
|
||||
dns_buf = (u_char*) TX_BUF;
|
||||
get_domain_name = dns_buf + MAX_DNSMSG_SIZE;
|
||||
|
||||
query_data = querydata;
|
||||
|
||||
if(querydata==BYNAME) qname = domain_name;
|
||||
else
|
||||
{
|
||||
qname = get_domain_name + MAX_QNAME_LEN;
|
||||
|
||||
////---- MODIFY_2006_06_05 :
|
||||
/*2. Host address to host name translation
|
||||
This function will often follow the form of previous
|
||||
functions. Given a 32 bit IP address, the caller wants a
|
||||
character string. The octets of the IP address are reversed,
|
||||
used as name components, and suffixed with "IN-ADDR.ARPA". A
|
||||
type PTR query is used to get the RR with the primary name of
|
||||
the host. For example, a request for the host name
|
||||
corresponding to IP address 1.2.3.4 looks for PTR RRs for
|
||||
domain name "4.3.2.1.IN-ADDR.ARPA". */
|
||||
|
||||
// Check little or big endian
|
||||
PRINTLN1("domain_ip=%08lx",domain_ip);
|
||||
if(*domain_ip != ntohl(*domain_ip)) // if domain_ip is little-endian
|
||||
strcpy(qname,inet_ntoa(*domain_ip));
|
||||
else strcpy(qname,inet_ntoa(swapl(*domain_ip))); // if domain_ip is big-endian then make the reverse ip address string.
|
||||
////---- MODIFY_END
|
||||
|
||||
strcat(qname,".in-addr.arpa");
|
||||
}
|
||||
if(socket(s, Sn_MR_UDP, 0, 0) == 0) return 0;
|
||||
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN2("Querying server %s by %s", inet_ntoa(ntohl(dnsip)), qname);
|
||||
#endif
|
||||
|
||||
len = dns_makequery(OP_QUERY, qname); // create DNS query
|
||||
if(!len)
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN("Fail to make query");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG_DNS
|
||||
/*
|
||||
{
|
||||
int i;
|
||||
DPRINT1("%d length dns query is made.",len);
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
if(!(i % 0x10)) DPRINTLN("");
|
||||
DPRINT1("%02X ",dns_buf[i]);
|
||||
}
|
||||
DPRINTLN("\r\n");
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
sendto(s, dns_buf, len, (u_char*)&dnsip, IPPORT_DOMAIN); // DNS query send to DNS server
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN1("sent dns query to DNS server : [%s]",inet_ntoa(ntohl(dnsip)));
|
||||
#endif
|
||||
while (elapse-- > 0)
|
||||
{
|
||||
wait_10ms(1); // wait until Domain name resolution
|
||||
if ((len = getSn_RX_RSR(s)) > 0)
|
||||
{
|
||||
if (len > MAX_DNSMSG_SIZE) len = MAX_DNSMSG_SIZE;
|
||||
len = recvfrom(s, dns_buf, len, (char*)&dnsip, &port);
|
||||
reponse_received = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(s);
|
||||
if(!reponse_received)
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN("No response from DNS server");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG_DNS
|
||||
/*
|
||||
{
|
||||
int i;
|
||||
DPRINT2("%d received resonse from DNS Server[%s]\r\n",len,inet_ntoa(ntohl(dnsip)));
|
||||
for(i = 0; i < len ; i++)
|
||||
{
|
||||
if(!(i%0x10)) DPRINTLN("");
|
||||
DPRINT1("%02X ",dns_buf[i]);
|
||||
}
|
||||
DPRINTLN("\r\n");
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
if(!dns_parse_reponse()) // Convert to local format
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN("Fail to parse reponse from DNS server");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
if(query_data == BYNAME) *domain_ip = get_domain_ip;
|
||||
else strcpy(domain_name, get_domain_name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Create query message for transferring to DNS server
|
||||
@return size of query message
|
||||
*/
|
||||
static int dns_makequery(
|
||||
u_char op, /**< queryÀÇ opcode (input) */
|
||||
char * qname /**< size of query message */
|
||||
)
|
||||
{
|
||||
u_char* query = dns_buf;
|
||||
u_char* domain_tok;
|
||||
u_int domain_len;
|
||||
u_int qtype = (query_data) ? TYPE_PTR : TYPE_A; // Domain name pointer or Host Address
|
||||
u_int qclass = CLASS_IN; // Internet
|
||||
|
||||
/* Make Qurey Header */
|
||||
memset(dns_buf,0,MAX_DNSMSG_SIZE);
|
||||
*((u_short*)query) = htons(dns_id);
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINT2("query : id = %02X%02X, ",query[0],query[1]);
|
||||
#endif
|
||||
|
||||
query += 2;
|
||||
|
||||
*query = MAKE_FLAG0(QR_QUERY,op,0,0,1); // Recursion desired
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINT1("opcode = %02X, ",*query);
|
||||
#endif
|
||||
query++;
|
||||
*query = MAKE_FLAG1(0,0,0);
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN1("rcode = %02X",*query);
|
||||
#endif
|
||||
query++;
|
||||
|
||||
*((u_short*)query) = htons(1);
|
||||
|
||||
query = dns_buf + DHDR_SIZE;
|
||||
|
||||
/* Make Question Section */
|
||||
while(1) // fill in QNAME filed with domain_name
|
||||
{
|
||||
domain_tok = strchr(qname,'.');
|
||||
if(domain_tok) domain_len = ((u_int)domain_tok - (u_int)qname) & 0xFF;
|
||||
else domain_len = strlen(qname);
|
||||
if(domain_len > 63)
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN("Invalid label length because labels are restricted to 63 octets or less.");
|
||||
#endif
|
||||
return 0; // since the label must begin with two zero bits because labels are restricted to 63 octets or less.
|
||||
}
|
||||
*query++ = domain_len;
|
||||
memcpy(query,qname,domain_len);
|
||||
qname += domain_len+1;
|
||||
query += domain_len;
|
||||
if(!domain_tok) break;
|
||||
}
|
||||
*query++ = '\0'; // terminate QNAME field with 'NULL'
|
||||
|
||||
// fill in QTYPE field, for host address
|
||||
*query++ = qtype >> 8 & 0xFF;
|
||||
*query++ = qtype & 0xFF;
|
||||
|
||||
// fill in QCLASS field, for internet
|
||||
*query++ = qclass >> 8 & 0xFF;
|
||||
*query++ = qclass & 0xFF;
|
||||
|
||||
return (int)(query - dns_buf); // return the size of generated query
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Analyze received DNS message packet and store it into structure
|
||||
@return success - 1, fail - 0
|
||||
*/
|
||||
static int dns_parse_reponse(void)
|
||||
{
|
||||
u_int i;
|
||||
DHDR dhdr;
|
||||
char* cur_ptr = dns_buf;
|
||||
|
||||
|
||||
dhdr.id = ntohs(*((u_short*)cur_ptr));
|
||||
if(dhdr.id != dns_id)
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN2("Responsed ID != Query ID : %d ! = %d",dhdr.id, dns_id);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
dns_id++;
|
||||
cur_ptr += 2;
|
||||
dhdr.flag0 = *cur_ptr++;
|
||||
dhdr.flag1 = *cur_ptr++;
|
||||
if(!(dhdr.flag0 & 0x80)|| !(dhdr.flag1 & 0x80) )
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN2("No reponse message, flag0 = 0x%02X, flag1 = 0x%02X",dhdr.flag0,dhdr.flag1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
if(dhdr.flag1 & 0x0F)
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINT("Error of reponse : ");
|
||||
switch(dhdr.flag1 & 0x0F)
|
||||
{
|
||||
case RC_FORMAT_ERROR:
|
||||
DPRINTLN("Format Error");
|
||||
break;
|
||||
case RC_SERVER_FAIL:
|
||||
DPRINTLN("Server failure");
|
||||
break;
|
||||
case RC_NAME_ERROR:
|
||||
DPRINTLN("Name Error");
|
||||
break;
|
||||
case RC_NOT_IMPL:
|
||||
DPRINTLN("Not Implemented");
|
||||
break;
|
||||
case RC_REFUSED:
|
||||
DPRINTLN("Refused");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
dhdr.qdcount = ntohs(*((u_short*)cur_ptr));
|
||||
cur_ptr += 2;
|
||||
dhdr.ancount = ntohs(*((u_short*)cur_ptr));
|
||||
cur_ptr += 2;
|
||||
dhdr.nscount = ntohs(*((u_short*)cur_ptr));
|
||||
cur_ptr += 2;
|
||||
dhdr.arcount = ntohs(*((u_short*)cur_ptr));
|
||||
cur_ptr += 2;
|
||||
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN2("Response : question count = %d, answer count = %d",dhdr.qdcount,dhdr.ancount);
|
||||
DPRINTLN2("Response : authority count = %d, additiional count = %d",dhdr.nscount,dhdr.arcount);
|
||||
#endif
|
||||
|
||||
/* Now parse the variable length sections */
|
||||
for(i = 0; i < dhdr.qdcount; i++)
|
||||
{
|
||||
cur_ptr = dns_parse_question(cur_ptr); // Question section
|
||||
if(!cur_ptr)
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN1("Fail to parse question section%d",i);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* parse resource records */
|
||||
|
||||
for(i=0; i < dhdr.ancount; i++)
|
||||
{
|
||||
cur_ptr = dns_answer(cur_ptr); // Answer section
|
||||
if(!cur_ptr)
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN1("Fail to parse answer section%d",i);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(i = 0; i < dhdr.nscount; i++) // Name server (authority) section
|
||||
{
|
||||
// if you need to authority section, insert user parse fuction into here.
|
||||
}
|
||||
|
||||
for(i = 0; i < dhdr.arcount; i++) // Additional section
|
||||
{
|
||||
// if you need to additional section , insert user parse fuction into here.
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Parse question section in the DNS query
|
||||
@return success - 1, fail - 0
|
||||
*/
|
||||
static u_char * dns_parse_question(
|
||||
u_char * cp /**< curruent pointer to be parsed */
|
||||
)
|
||||
{
|
||||
int len;
|
||||
char name[MAX_QNAME_LEN];
|
||||
|
||||
len = parse_name(cp, name, sizeof(name));
|
||||
if(!len)
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN("Fail to parse (Q)NAME field");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
cp += len;
|
||||
cp += 2; // skip type
|
||||
cp += 2; // skip class
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN1("In question section, (Q)NAME field value : %s",name);
|
||||
#endif
|
||||
return cp;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Parse answer section in the DNS query. Store resolved IP address into destination address
|
||||
@return end address of answer section, fail - 0
|
||||
*/
|
||||
static u_char * dns_answer(
|
||||
u_char *cp
|
||||
)
|
||||
{
|
||||
int len, type;
|
||||
char qname[MAX_QNAME_LEN];
|
||||
u_long tip;
|
||||
|
||||
len = parse_name(cp, qname, sizeof(qname));
|
||||
|
||||
if(!len) return 0;
|
||||
|
||||
cp += len;
|
||||
type = *cp++;
|
||||
type = (type << 8) + (u_int)*cp++; // type
|
||||
cp += 2; // skip class
|
||||
cp += 4; // skip ttl
|
||||
cp += 2; // skip len
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case TYPE_A:
|
||||
tip = 0;
|
||||
*((u_char*)&tip) = *cp++; // Network odering
|
||||
*(((u_char*)&tip) + 1) = *cp++;
|
||||
*(((u_char*)&tip) + 2) = *cp++;
|
||||
*(((u_char*)&tip) + 3) = *cp++;
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN1("RRs : TYPE_A = %s", inet_ntoa(ntohl(tip)));
|
||||
#endif
|
||||
if(query_data == BYNAME) get_domain_ip = tip;
|
||||
break;
|
||||
case TYPE_CNAME:
|
||||
case TYPE_MB:
|
||||
case TYPE_MG:
|
||||
case TYPE_MR:
|
||||
case TYPE_NS:
|
||||
case TYPE_PTR:
|
||||
len = parse_name(cp, qname, sizeof(qname)); // These types all consist of a single domain name
|
||||
if(!len) return 0; // convert it to ascii format
|
||||
cp += len;
|
||||
if(query_data == BYIP && type == TYPE_PTR)
|
||||
{
|
||||
strcpy(get_domain_name,qname);
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN1("RRs : TYPE_PTR = %s",qname);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case TYPE_HINFO:
|
||||
len = *cp++;
|
||||
cp += len;
|
||||
|
||||
len = *cp++;
|
||||
cp += len;
|
||||
break;
|
||||
case TYPE_MX:
|
||||
cp += 2;
|
||||
len = parse_name(cp, qname, sizeof(qname)); // Get domain name of exchanger
|
||||
if(!len)
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN("TYPE_MX : Fail to get domain name of exechanger");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
cp += len;
|
||||
break;
|
||||
case TYPE_SOA:
|
||||
len = parse_name(cp, qname, sizeof(qname)); // Get domain name of name server
|
||||
if(!len)
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN("TYPE_SOA : Fail to get domain name of name server");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
cp += len;
|
||||
|
||||
len = parse_name(cp, qname, sizeof(qname)); // Get domain name of responsible person
|
||||
if(!len)
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN("TYPE_SOA : Fail to get domain name of responsible person");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
cp += len;
|
||||
|
||||
cp += 4;
|
||||
cp += 4;
|
||||
cp += 4;
|
||||
cp += 4;
|
||||
cp += 4;
|
||||
break;
|
||||
case TYPE_TXT:
|
||||
break; // Just stash
|
||||
default:
|
||||
break; // Ignore
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Parse answer section in the DNS query. Store resolved IP address into destination address
|
||||
@return end address of answer section, fail - 0
|
||||
*/
|
||||
static int parse_name(
|
||||
char* cp, /**< Convert a compressed domain name to the human-readable form */
|
||||
char* qname, /**< store human-readable form(input,output); */
|
||||
u_int qname_maxlen /**< qname_max_len - max length of qname(input) */
|
||||
)
|
||||
{
|
||||
u_int slen; // Length of current segment
|
||||
int clen = 0; // Total length of compressed name
|
||||
int indirect = 0; // Set if indirection encountered
|
||||
int nseg = 0; // Total number of label in name
|
||||
|
||||
for(;;)
|
||||
{
|
||||
slen = *cp++; // Length of this segment
|
||||
if (!indirect) clen++;
|
||||
|
||||
if ((slen & 0xc0) == 0xc0) // Is used in compression scheme?
|
||||
{
|
||||
cp = &dns_buf[((slen & 0x3f)<<8) + *cp]; // Follow indirection
|
||||
if(!indirect) clen++;
|
||||
indirect = 1;
|
||||
slen = *cp++;
|
||||
}
|
||||
|
||||
if (slen == 0) // zero length == all done
|
||||
break;
|
||||
|
||||
if (!indirect) clen += slen;
|
||||
|
||||
if((qname_maxlen -= slen+1) < 0)
|
||||
{
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN("Not enough memory");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
while (slen-- != 0) *qname++ = (char)*cp++;
|
||||
*qname++ = '.';
|
||||
|
||||
nseg++;
|
||||
}
|
||||
|
||||
if(nseg == 0) *qname++ = '.'; // Root name; represent as single dot
|
||||
else --qname;
|
||||
|
||||
*qname = '\0';
|
||||
#ifdef DEBUG_DNS
|
||||
DPRINTLN1("Result of parsing (Q)NAME field : %s",qname);
|
||||
#endif
|
||||
return clen; // Length of compressed message // Length of compressed message
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief gethostbyaddr function retrieves the host domain name corresponding to a network address
|
||||
@return success - 1, fail - 0
|
||||
*/
|
||||
int gethostbyaddr(
|
||||
u_long ipaddr, /**< 32bit network ordering ip address */
|
||||
char* domain /**< poniter to domain name string resolved from dns server */
|
||||
)
|
||||
{
|
||||
SOCKET s;
|
||||
//get_netconf(&NetConf);
|
||||
if(dns_server_ip == 0 || dns_server_ip == 0xFFFFFFFF)
|
||||
{
|
||||
DPRINTLN("DNS server ip address is not configured.");
|
||||
return 0;
|
||||
}
|
||||
if((s=getSocket(SOCK_CLOSED,0)) == MAX_SOCK_NUM)
|
||||
{
|
||||
DPRINTLN("All socket is alreay used. Not found free socket.");
|
||||
return 0;
|
||||
}
|
||||
if(!dns_query(s,dns_server_ip,domain,&ipaddr,BYIP,1000))
|
||||
{
|
||||
DPRINTLN1("Fail to communicate with DNS server[%s]",inet_ntoa(ntohl(dns_server_ip)));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief gethostbyname function retrieves host ip address corresponding to a host name
|
||||
@return success - host ip address(32bit network odering address), fail - 0
|
||||
*/
|
||||
u_long gethostbyname(
|
||||
char* hostname /**< host domain name */
|
||||
)
|
||||
{
|
||||
SOCKET s;
|
||||
u_long hostip=0;
|
||||
|
||||
if(dns_server_ip == 0 || dns_server_ip == 0xFFFFFFFF)
|
||||
{
|
||||
PRINTLN("DNS server ip address is not configured.");
|
||||
return 0;
|
||||
}
|
||||
PRINTLN1("DNS SERVER : %s",inet_ntoa(ntohl(dns_server_ip)));
|
||||
if((s=getSocket(SOCK_CLOSED,0)) == MAX_SOCK_NUM)
|
||||
{
|
||||
PRINTLN("All socket is alreay used. Not found free socket.");
|
||||
return 0;
|
||||
}
|
||||
if(!dns_query(s,dns_server_ip,hostname,&hostip,BYNAME,1000))
|
||||
{
|
||||
PRINTLN1("Fail to communicate with DNS server[%s]",inet_ntoa(ntohl(dns_server_ip)));
|
||||
hostip = 0;
|
||||
}
|
||||
return hostip;
|
||||
}
|
@ -0,0 +1,329 @@
|
||||
/**
|
||||
@file dns.h
|
||||
@brief Implement Simple Domain Name System Protocol
|
||||
*/
|
||||
|
||||
#ifndef __DNS_H
|
||||
#define __DNS_H
|
||||
|
||||
/*
|
||||
<Message Format>
|
||||
+---------------------+
|
||||
| Header |
|
||||
+---------------------+
|
||||
| Question | the question for the name server
|
||||
+---------------------+
|
||||
| Answer | Resource Records answering the question
|
||||
+---------------------+
|
||||
| Authority | Resource Records pointing toward an authority
|
||||
+---------------------+
|
||||
| Additional | Resource Records holding additional information
|
||||
+---------------------+
|
||||
|
||||
As follow, example of DNS Standard Query
|
||||
+---------------------------------------------------+
|
||||
Header | OPCODE=SQUERY |
|
||||
+---------------------------------------------------+
|
||||
Question | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=A |
|
||||
+---------------------------------------------------+
|
||||
Answer | <empty> |
|
||||
+---------------------------------------------------+
|
||||
Authority | <empty> |
|
||||
+---------------------------------------------------+
|
||||
Additional | <empty> |
|
||||
+---------------------------------------------------+
|
||||
|
||||
As follow, example of DNS response
|
||||
+---------------------------------------------------+
|
||||
Header | OPCODE=SQUERY, RESPONSE, AA |
|
||||
+---------------------------------------------------+
|
||||
Question | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=A |
|
||||
+---------------------------------------------------+
|
||||
Answer | SRI-NIC.ARPA. 86400 IN A 26.0.0.73 |
|
||||
| 86400 IN A 10.0.0.51 |
|
||||
+---------------------------------------------------+
|
||||
Authority | <empty> |
|
||||
+---------------------------------------------------+
|
||||
Additional | <empty> |
|
||||
+---------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* QCLASS values
|
||||
|
||||
CLASS fields appear in resource records. The following CLASS mnemonics
|
||||
and values are defined:
|
||||
*/
|
||||
/* CLASS */
|
||||
#define CLASS_IN 1 /**< the Internet */
|
||||
#define CLASS_CS 2 /**< the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
|
||||
#define CLASS_CH 3 /**< the CHAOS class */
|
||||
#define CLASS_HS 4 /**< Hesiod [Dyer 87] */
|
||||
/* QCLASS */
|
||||
#define QCLASS_ANY 255 /**< any class */
|
||||
|
||||
/* QTYPE values
|
||||
|
||||
TYPE fields are used in resource records. Note that these types are a subset of QTYPEs.
|
||||
*/
|
||||
/* TYPE */
|
||||
#define TYPE_A 1 /**< The ARPA Internet */
|
||||
#define TYPE_NS 2 /**< an authoritative name server */
|
||||
#define TYPE_MD 3 /**< a mail destination (Obsolete - use MX) */
|
||||
#define TYPE_MF 4 /**< a mail forwarder (Obsolete - use MX) */
|
||||
#define TYPE_CNAME 5 /**< the canonical name for an alias */
|
||||
#define TYPE_SOA 6 /**< marks the start of a zone of authority */
|
||||
#define TYPE_MB 7 /**< a mailbox domain name (EXPERIMENTAL) */
|
||||
#define TYPE_MG 8 /**< a mail group member (EXPERIMENTAL) */
|
||||
#define TYPE_MR 9 /**< a mail rename domain name (EXPERIMENTAL)*/
|
||||
#define TYPE_NULL 10 /**< a null RR (EXPERIMENTAL) */
|
||||
#define TYPE_WKS 11 /**< a well known service description */
|
||||
#define TYPE_PTR 12 /**< a domain name pointer */
|
||||
#define TYPE_HINFO 13 /**< host information */
|
||||
#define TYPE_MINFO 14 /**< mailbox or mail list information */
|
||||
#define TYPE_MX 15 /**< mail exchange */
|
||||
#define TYPE_TXT 16 /**< text strings */
|
||||
/* QTYPE */
|
||||
#define QTYPE_AXFR 252 /**< A request for a transfer of an entire zone */
|
||||
#define QTYPE_MAILB 253 /**< A request for mailbox-related records (MB, MG or MR) */
|
||||
#define QTYPE_MAILA 254 /**< A request for mail agent RRs (Obsolete - see MX) */
|
||||
#define QTYPE_TYPE_ALL 255 /**< A request for all records */
|
||||
|
||||
|
||||
|
||||
#define INITRTT 2000L /**< Initial smoothed response time */
|
||||
#define MAXCNAME 10 /**< Maximum amount of cname recursion */
|
||||
|
||||
|
||||
/* Round trip timing parameters */
|
||||
#define AGAIN 8 /**< Average RTT gain = 1/8 */
|
||||
#define LAGAIN 3 /**< Log2(AGAIN) */
|
||||
#define DGAIN 4 /**< Mean deviation gain = 1/4 */
|
||||
#define LDGAIN 2 /**< log2(DGAIN) */
|
||||
|
||||
#define IPPORT_DOMAIN 53
|
||||
|
||||
/* Header for all domain messages */
|
||||
/*
|
||||
1 1 1 1 1 1
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| ID |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| QDCOUNT |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| ANCOUNT |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| NSCOUNT |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| ARCOUNT |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
*/
|
||||
/*A four bit field that specifies kind of query in this
|
||||
message. This value is set by the originator of a query
|
||||
and copied into the response. The values are:
|
||||
*/
|
||||
#define OP_QUERY 0 /**< a standard query (QUERY) */
|
||||
#define OP_IQUREY 1 /**< an inverse query (IQUERY) */
|
||||
#define OP_STATUS 2 /**< a server status request (STATUS)*/
|
||||
|
||||
/* A one bit field that specifies whether this message is a query (0), or a response (1). */
|
||||
#define QR_QUERY 0
|
||||
#define QR_RESPONSE 1
|
||||
|
||||
/* Response code - this 4 bit field is set as part of
|
||||
responses. The values have the following interpretation:
|
||||
*/
|
||||
|
||||
#define RC_NO_ERROR 0 /**< No error condition */
|
||||
#define RC_FORMAT_ERROR 1 /**< Format error - The name server was unable to interpret the query. */
|
||||
#define RC_SERVER_FAIL 2 /**< Server failure - The name server was unable to process this query due to a problem with the name server. */
|
||||
#define RC_NAME_ERROR 3 /**< Name Error - Meaningful only for responses from an authoritative name server, this code signifies that the domain name referenced in the query does not exist.*/
|
||||
#define RC_NOT_IMPL 4 /**< Not Implemented - The name server does not support the requested kind of query.*/
|
||||
#define RC_REFUSED 5 /**< Refused - The name server refuses to perform the specified operation for policy reasons.
|
||||
For example, a name server may not wish to provide the information to the particular requester,
|
||||
or a name server may not wish to perform a particular operation (e.g., zone */
|
||||
|
||||
#define DHDR_SIZE 12
|
||||
|
||||
|
||||
/**
|
||||
@brief Header for all domain messages
|
||||
*/
|
||||
typedef struct _DHDR
|
||||
{
|
||||
u_int id; /**< Identification */
|
||||
u_char flag0;
|
||||
u_char flag1;
|
||||
u_int qdcount; /**< Question count */
|
||||
u_int ancount; /**< Answer count */
|
||||
u_int nscount; /**< Authority (name server) count */
|
||||
u_int arcount; /**< Additional record count */
|
||||
}DHDR;
|
||||
|
||||
/* rd : Recursion desired , tc : Truncation, aa : Authoratative answer, opcode : op code = OP_QUREY, OP_IQUREY, OP_STAUTS, qr : Query/Response */
|
||||
#define MAKE_FLAG0(qr,op,aa,tc,rd) ( ((qr & 0x01) << 7) + ((op & 0x0F) << 3) + ((aa & 0x01) << 2) + ((tc & 0x01) << 1) + (rd & 0x01) )
|
||||
|
||||
/* rcode : Response code, z : Reserved for future use. Must be zero in all queries and responses, */
|
||||
/* ra : Recursion Available - this be is set or cleared in a response, and denotes whether recursive query support is available in the name server.*/
|
||||
#define MAKE_FLAG1(ra,z,rcode) ( ((ra & 0x01) << 7) + ((z & 0x07) << 4) + (rcode & 0x0F) )
|
||||
|
||||
/*
|
||||
<QUESTION FORMAT >
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| |
|
||||
/ QNAME /
|
||||
/ /
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| QTYPE |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| QCLASS |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
|
||||
where:
|
||||
|
||||
QNAME a domain name represented as a sequence of labels, where
|
||||
each label consists of a length octet followed by that
|
||||
number of octets. The domain name terminates with the
|
||||
zero length octet for the null label of the root. Note
|
||||
that this field may be an odd number of octets; no
|
||||
padding is used.
|
||||
|
||||
QTYPE a two octet code which specifies the type of the query.
|
||||
The values for this field include all codes valid for a
|
||||
TYPE field, together with some more general codes which
|
||||
can match more than one type of RR.
|
||||
|
||||
QCLASS a two octet code that specifies the class of the query.
|
||||
For example, the QCLASS field is IN for the Internet.
|
||||
*/
|
||||
|
||||
/**
|
||||
@brief QUESTION FORMAT
|
||||
*/
|
||||
typedef struct _QUESTION
|
||||
{
|
||||
// char* qname; // Variable length data
|
||||
u_int qtype;
|
||||
u_int qclass;
|
||||
}DQST;
|
||||
|
||||
|
||||
/*
|
||||
Resource record format
|
||||
|
||||
The answer, authority, and additional sections all share the same
|
||||
format: a variable number of resource records, where the number of
|
||||
records is specified in the corresponding count field in the header.
|
||||
Each resource record has the following format:
|
||||
1 1 1 1 1 1
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| |
|
||||
/ /
|
||||
/ NAME /
|
||||
| |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| TYPE |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| CLASS |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| TTL |
|
||||
| |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| RDLENGTH |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
|
||||
/ RDATA /
|
||||
/ /
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
|
||||
where:
|
||||
|
||||
NAME a domain name to which this resource record pertains.
|
||||
In order to reduce the size of messages, the domain system utilizes a
|
||||
compression scheme which eliminates the repetition of domain names in a
|
||||
message. In this scheme, an entire domain name or a list of labels at
|
||||
the end of a domain name is replaced with a pointer to a prior occurance
|
||||
of the same name.
|
||||
The pointer takes the form of a two octet sequence:
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| 1 1| OFFSET |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
The first two bits are ones. This allows a pointer to be distinguished
|
||||
from a label, since the label must begin with two zero bits because
|
||||
labels are restricted to 63 octets or less. (The 10 and 01 combinations
|
||||
are reserved for future use.) The OFFSET field specifies an offset from
|
||||
the start of the message (i.e., the first octet of the ID field in the
|
||||
domain header). A zero offset specifies the first byte of the ID field,
|
||||
etc.
|
||||
The compression scheme allows a domain name in a message to be
|
||||
represented as either:
|
||||
- a sequence of labels ending in a zero octet
|
||||
- a pointer
|
||||
- a sequence of labels ending with a pointer
|
||||
|
||||
TYPE two octets containing one of the RR type codes. This
|
||||
field specifies the meaning of the data in the RDATA
|
||||
field.
|
||||
|
||||
CLASS two octets which specify the class of the data in the
|
||||
RDATA field.
|
||||
|
||||
TTL a 32 bit unsigned integer that specifies the time
|
||||
interval (in seconds) that the resource record may be
|
||||
cached before it should be discarded. Zero values are
|
||||
interpreted to mean that the RR can only be used for the
|
||||
transaction in progress, and should not be cached.
|
||||
|
||||
RDLENGTH an unsigned 16 bit integer that specifies the length in
|
||||
octets of the RDATA field.
|
||||
|
||||
RDATA a variable length string of octets that describes the
|
||||
resource. The format of this information varies
|
||||
according to the TYPE and CLASS of the resource record.
|
||||
For example, the if the TYPE is A and the CLASS is IN,
|
||||
the RDATA field is a 4 octet ARPA Internet address.
|
||||
*/
|
||||
|
||||
#define COMPRESSION_SCHEME 0xC0
|
||||
|
||||
/**
|
||||
@brief Resource record format
|
||||
|
||||
The answer, authority, and additional sections all share the same
|
||||
format: a variable number of resource records, where the number of
|
||||
records is specified in the corresponding count field in the header.
|
||||
Each resource record has the following format:
|
||||
*/
|
||||
typedef struct _RESOURCE_RECORD
|
||||
{
|
||||
// char* _name; // Variable length data
|
||||
u_int _type;
|
||||
u_int _class;
|
||||
u_int _ttl;
|
||||
u_int _rdlen;
|
||||
// char* _rdata; // Variable length data
|
||||
}DRR;
|
||||
|
||||
|
||||
|
||||
|
||||
#define MAX_DNSMSG_SIZE 512 /**< Maximum size of DNS message */
|
||||
#define MAX_DOMAINNAME_LEN 50 /**< Maximum size of domain name */
|
||||
#define MAX_QNAME_LEN 128 /**< Maximum size of qname */
|
||||
|
||||
|
||||
typedef enum _QUERYDATA{BYNAME,BYIP}QUERYDATA; /* Query type */
|
||||
|
||||
|
||||
|
||||
/* Resolve domain name or ip address from DNS server */
|
||||
extern u_char dns_query(SOCKET s, u_long dnsip, u_char * domain_name, u_long* domain_ip,QUERYDATA querydata, u_int elapse);
|
||||
|
||||
extern int gethostbyaddr(u_long ipaddr,char* domain); // gethostbyaddr function retrieves the host domain name corresponding to a network address
|
||||
extern u_long gethostbyname(char* hostname); // gethostbyname function retrieves host ip address corresponding to a host name
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,178 @@
|
||||
/**
|
||||
@file main.c
|
||||
@brief DNS source ( for W5100 )
|
||||
*/
|
||||
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
//#include <avr/signal.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include "delay.h"
|
||||
#include "mcu.h"
|
||||
|
||||
#include "serial.h"
|
||||
#include "sockutil.h"
|
||||
#include "socket.h"
|
||||
//#include "timer.h"
|
||||
#include "dns.h"
|
||||
|
||||
#include "w5100.h"
|
||||
|
||||
/*
|
||||
********************************************************************************
|
||||
Define Part
|
||||
********************************************************************************
|
||||
*/
|
||||
#define DEFAULT_NET_MEMALLOC 0x55 /**< Default iinchip memory allocation */
|
||||
|
||||
#define LED_AVR_PORT_VAL PORTG
|
||||
#define LED_AVR_PORT_DIR DDRG
|
||||
|
||||
#define LED_PIN_0 3
|
||||
#define LED_PIN_1 4
|
||||
|
||||
/*
|
||||
********************************************************************************
|
||||
Local Variable Declaration Section
|
||||
********************************************************************************
|
||||
*/
|
||||
u_char URL[] = "www.wiznet.co.kr";
|
||||
extern u_long dns_server_ip; /**< instead of "NETCONF" */
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
Function Prototype Declaration Part
|
||||
*******************************************************************************
|
||||
*/
|
||||
static void led_off(u_char led);
|
||||
static void led_on(u_char led);
|
||||
static void led_init(void);
|
||||
static void SetIP(void);
|
||||
|
||||
/*
|
||||
********************************************************************************
|
||||
Function Implementation Part
|
||||
********************************************************************************
|
||||
*/
|
||||
static void led_off(u_char led)
|
||||
{
|
||||
LED_AVR_PORT_VAL &= ~(1 << (LED_PIN_0+led));
|
||||
}
|
||||
|
||||
static void led_on(u_char led)
|
||||
{
|
||||
LED_AVR_PORT_VAL |= (1 << (LED_PIN_0+led));
|
||||
}
|
||||
|
||||
static void led_init(void)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
LED_AVR_PORT_DIR |= (1<<LED_PIN_0) | (1<<LED_PIN_1);
|
||||
for(i = 0; i < 5; i++)
|
||||
{
|
||||
led_on(0);
|
||||
led_on(1);
|
||||
wait_10ms(50);
|
||||
led_off(0);
|
||||
led_off(1);
|
||||
wait_10ms(50);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief set the IP, subnet, gateway address
|
||||
*/
|
||||
static void SetIP(void)
|
||||
{
|
||||
u_char ip[6];
|
||||
|
||||
// MAC address
|
||||
ip[0] = 0x00; ip[1] = 0x08; ip[2] = 0xDC; ip[3] = 0x00; ip[4] = 0x00; ip[5] = 0x4F;
|
||||
setSHAR( ip );
|
||||
|
||||
// subnet mask
|
||||
ip[0] = 255;ip[1] = 255;ip[2] = 255;ip[3] = 224;
|
||||
setSUBR( ip );
|
||||
|
||||
// gateway address
|
||||
ip[0] = 211;ip[1] = 46;ip[2] = 117;ip[3] = 94;
|
||||
setGAR( ip );
|
||||
|
||||
// ip address
|
||||
ip[0] = 211;ip[1] = 46;ip[2] = 117;ip[3] = 84;
|
||||
setSIPR( ip );
|
||||
|
||||
// Set DNS server IP address
|
||||
dns_server_ip = htonl(inet_addr( "168.126.63.1" ));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@mainpage W5100 Firmware Source for DNS
|
||||
@section intro Introduction
|
||||
- Introduction : supported DNS
|
||||
@section CREATEINFO Author
|
||||
- author : www.wiznet.co.kr
|
||||
- date : 2007.1.2
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
u_long wiznet_ip = 0;
|
||||
|
||||
mcu_init();
|
||||
uart_init(0,7);
|
||||
|
||||
printf("\r\n*** DNS Test using W5100 ");
|
||||
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
|
||||
printf("[DIRECT MODE]");
|
||||
#elif(__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__) /* INDIRECT MODE I/F */
|
||||
printf("[INDIRECT MODE]");
|
||||
#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
|
||||
printf("[SPI MODE]");
|
||||
#else
|
||||
#error "unknown bus type"
|
||||
#endif
|
||||
printf(" ***\r\n");
|
||||
|
||||
printf("******* Firmware Version : %d.%d.%d.%d *******\r\n",
|
||||
(u_char)(FW_VERSION>>24),
|
||||
(u_char)(FW_VERSION>>16),
|
||||
(u_char)(FW_VERSION>>8),
|
||||
(u_char)(FW_VERSION) );
|
||||
|
||||
wait_10ms(100);
|
||||
|
||||
led_init();
|
||||
iinchip_init();
|
||||
|
||||
// Set IP, subnet, gateway address
|
||||
SetIP();
|
||||
#ifdef __DEF_IINCHIP_INT__
|
||||
setIMR(0xEF);
|
||||
#endif
|
||||
sysinit(DEFAULT_NET_MEMALLOC,DEFAULT_NET_MEMALLOC);
|
||||
|
||||
if ( (wiznet_ip = gethostbyname(URL)) != 0 )
|
||||
{
|
||||
printf("www.wiznet.co.kr => %s", inet_ntoa( htonl(wiznet_ip) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Can'g get IP Address.\r\n");
|
||||
}
|
||||
printf("\r\n*** THANK YOU ***\r\n");
|
||||
|
||||
while(1);
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @file delay.c
|
||||
* @brief waiting functions
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "delay.h"
|
||||
|
||||
|
||||
//---- MODIFY_2005_10_31 : PM-A1 V1.1 --> V1.2 (16MHz --> 8MHz)
|
||||
void wait_1us(u_int cnt)
|
||||
{
|
||||
/* 16MHz : 16 CLK 1us : 1 + (1 + (1+1)*4 + 1 + (2+1))*cnt + 1 + 1*/
|
||||
/*
|
||||
asm volatile
|
||||
(
|
||||
"movw r24, %A0" "\n\t"
|
||||
"L_US:" "\n\t"
|
||||
"ldi r26, lo8(4)" "\n\t"
|
||||
"L_US0:" "\n\t"
|
||||
"dec r26" "\n\t"
|
||||
"brne L_US0" "\n\t"
|
||||
"sbiw r24, 1" "\n\t"
|
||||
"brne L_US" "\n\t"
|
||||
"nop" "\n\t"
|
||||
: :"r" (cnt)
|
||||
);
|
||||
*/
|
||||
/* 8MHz : 8 CLK 1us : 1 + (1*5 + (2+1))*cnt + 1 + 1*/
|
||||
asm volatile
|
||||
(
|
||||
"movw r24, %A0" "\n\t"
|
||||
"L_US:" "\n\t"
|
||||
"nop" "\n\t"
|
||||
"nop" "\n\t"
|
||||
"nop" "\n\t"
|
||||
"nop" "\n\t"
|
||||
"nop" "\n\t"
|
||||
"sbiw r24, 1" "\n\t"
|
||||
"brne L_US" "\n\t"
|
||||
"nop" "\n\t"
|
||||
: :"r" (cnt)
|
||||
);
|
||||
|
||||
}
|
||||
//---- END_MODIFY
|
||||
|
||||
/*
|
||||
********************************************************************************
|
||||
* WAIT FUNCTION
|
||||
*
|
||||
* Description : This function waits for 10 milliseconds
|
||||
* Arguments : cnt - is the time to wait
|
||||
* Returns : None
|
||||
* Note : Internal Function
|
||||
********************************************************************************
|
||||
*/
|
||||
void wait_10ms(u_int cnt)
|
||||
{
|
||||
for (; cnt; cnt--) wait_1ms(10);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
********************************************************************************
|
||||
* WAIT FUNCTION
|
||||
*
|
||||
* Description : This function waits for 1 milliseconds
|
||||
* Arguments : cnt - is the time to wait
|
||||
* Returns : None
|
||||
* Note : Internal Function
|
||||
********************************************************************************
|
||||
*/
|
||||
void wait_1ms(u_int cnt)
|
||||
{
|
||||
for (; cnt; cnt--) wait_1us(1000);
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @file delay.h
|
||||
* @brief header for waiting functions
|
||||
*/
|
||||
|
||||
#ifndef _DELAY_H
|
||||
#define _DELAY_H
|
||||
|
||||
extern void wait_1us(u_int cnt);
|
||||
|
||||
extern void wait_1ms(u_int cnt);
|
||||
|
||||
extern void wait_10ms(u_int cnt);
|
||||
|
||||
#endif
|
@ -0,0 +1,64 @@
|
||||
/**
|
||||
@file mcu.c
|
||||
@brief functions to initialize MCU
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "mcu.h"
|
||||
|
||||
|
||||
#define ATMEGA128_0WAIT 0
|
||||
#define ATMEGA128_1WAIT 1
|
||||
#define ATMEGA128_2WAIT 2
|
||||
#define ATMEGA128_3WAIT 3
|
||||
#define ATMEGA128_NUM_WAIT ATMEGA128_0WAIT
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize MCU
|
||||
*/
|
||||
void mcu_init(void)
|
||||
{
|
||||
cli();
|
||||
#ifndef __DEF_IINCHIP_INT__
|
||||
EICRA=0x00;
|
||||
EICRB=0x00;
|
||||
EIMSK=0x00;
|
||||
EIFR=0x00;
|
||||
#else
|
||||
EICRA = 0x00; // External Interrupt Control Register A clear
|
||||
EICRB = 0x02; // External Interrupt Control Register B clear // edge
|
||||
EIMSK = (1 << INT4); // External Interrupt Mask Register : 0x10
|
||||
EIFR = 0xFF; // External Interrupt Flag Register all clear
|
||||
DDRE &= ~(1 << INT4); // Set PE Direction
|
||||
PORTE |= (1 << INT4); // Set PE Default value
|
||||
#endif
|
||||
|
||||
#if (ATMEGA128_NUM_WAIT == ATMEGA128_0WAIT)
|
||||
MCUCR = 0x80;
|
||||
XMCRA=0x40;
|
||||
#elif (ATMEGA128_NUM_WAIT == ATMEGA128_1WAIT)
|
||||
MCUCR = 0xc0; // MCU control regiseter : enable external ram
|
||||
XMCRA=0x40; // External Memory Control Register A :
|
||||
// Low sector : 0x1100 ~ 0x7FFF
|
||||
// Upper sector : 0x8000 ~ 0xFFFF
|
||||
#elif (ATMEGA128_NUM_WAIT == ATMEGA128_2WAIT )
|
||||
MCUCR = 0x80;
|
||||
XMCRA=0x42;
|
||||
#elif ((ATMEGA128_NUM_WAIT == ATMEGA128_3WAIT)
|
||||
MCUCR = 0xc0;
|
||||
XMCRA=0x42;
|
||||
#else
|
||||
#error "unknown atmega128 number wait type"
|
||||
#endif
|
||||
sei(); // enable interrupts
|
||||
}
|
||||
|
||||
|
||||
void mcu_soft_reset(void)
|
||||
{
|
||||
asm volatile("jmp 0x0000");
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
/**
|
||||
@file mcu.h
|
||||
@brief
|
||||
*/
|
||||
|
||||
#ifndef _MCU_H
|
||||
#define _MCU_H
|
||||
|
||||
extern void mcu_init(void);
|
||||
extern void mcu_soft_reset(void);
|
||||
|
||||
#endif
|
@ -0,0 +1,66 @@
|
||||
/**
|
||||
@file mcu_define.h
|
||||
*/
|
||||
|
||||
#ifndef __MCU_DEFINE_H__
|
||||
#define __MCU_DEFINE_H__
|
||||
|
||||
|
||||
#define __MCU_AVR__ 1
|
||||
#define __MCU_TYPE__ __MCU_AVR__
|
||||
|
||||
//---- Refer "Rom File Maker Manual Vx.x.pdf"
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#define _ENDIAN_LITTLE_ 0 /**< This must be defined if system is little-endian alignment */
|
||||
#define _ENDIAN_BIG_ 1
|
||||
#define SYSTEM_ENDIAN _ENDIAN_LITTLE_
|
||||
|
||||
#define MAX_SOCK_NUM 4 /**< Maxmium number of socket */
|
||||
#define CLK_CPU 8000000 /**< 8Mhz(for serial) */
|
||||
|
||||
/* ## __DEF_IINCHIP_xxx__ : define option for iinchip driver *****************/
|
||||
//#define __DEF_IINCHIP_DBG__ /* involve debug code in driver (socket.c) */
|
||||
#define __DEF_IINCHIP_INT__ /**< involve interrupt service routine (socket.c) */
|
||||
//#define __DEF_IINCHIP_PPP__ /* involve pppoe routine (socket.c) */
|
||||
/* If it is defined, the source files(md5.h,md5.c) must be included in your project.
|
||||
Otherwize, the source files must be removed in your project. */
|
||||
|
||||
#define __DEF_IINCHIP_DIRECT_MODE__ 1
|
||||
#define __DEF_IINCHIP_INDIRECT_MODE__ 2
|
||||
#define __DEF_IINCHIP_SPI_MODE__ 3
|
||||
#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_DIRECT_MODE__
|
||||
//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_INDIRECT_MODE__
|
||||
//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_SPI_MODE__ /*Enable SPI_mode*/
|
||||
|
||||
|
||||
/**
|
||||
@brief __DEF_IINCHIP_MAP_xxx__ : define memory map for iinchip
|
||||
*/
|
||||
#define __DEF_IINCHIP_MAP_BASE__ 0x8000
|
||||
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
|
||||
#define COMMON_BASE __DEF_IINCHIP_MAP_BASE__
|
||||
#else
|
||||
#define COMMON_BASE 0x0000
|
||||
#endif
|
||||
#define __DEF_IINCHIP_MAP_TXBUF__ (COMMON_BASE + 0x4000) /* Internal Tx buffer address of the iinchip */
|
||||
#define __DEF_IINCHIP_MAP_RXBUF__ (COMMON_BASE + 0x6000) /* Internal Rx buffer address of the iinchip */
|
||||
|
||||
|
||||
#if (__MCU_TYPE__ == __MCU_AVR__)
|
||||
#ifdef __DEF_IINCHIP_INT__
|
||||
// iinchip use external interrupt 4
|
||||
#define IINCHIP_ISR_DISABLE() (EIMSK &= ~(0x10))
|
||||
#define IINCHIP_ISR_ENABLE() (EIMSK |= 0x10)
|
||||
#define IINCHIP_ISR_GET(X) (X = EIMSK)
|
||||
#define IINCHIP_ISR_SET(X) (EIMSK = X)
|
||||
#else
|
||||
#define IINCHIP_ISR_DISABLE()
|
||||
#define IINCHIP_ISR_ENABLE()
|
||||
#define IINCHIP_ISR_GET(X)
|
||||
#define IINCHIP_ISR_SET(X)
|
||||
#endif
|
||||
#else
|
||||
#error "unknown MCU type"
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,605 @@
|
||||
/*
|
||||
*
|
||||
@file serial.c
|
||||
@brief UART functions for EVBAVR VER 1.0 (AVR-GCC Compiler)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "serial.h"
|
||||
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
typedef struct _UARTHANDLER
|
||||
{
|
||||
char (*uart_get_handler)(FILE *);
|
||||
void (*uart_put_handler)(char, FILE *);
|
||||
}UARTHANDLER;
|
||||
#else
|
||||
typedef struct _UARTHANDLER
|
||||
{
|
||||
char (*uart_get_handler)(void);
|
||||
void (*uart_put_handler)(char);
|
||||
}UARTHANDLER;
|
||||
#endif
|
||||
|
||||
|
||||
#define SET_MY_XOFF_STATE(X) (bXONOFF[X] |= 0x01)
|
||||
#define SET_MY_XON_STATE(X) (bXONOFF[X] &= ~(0x01))
|
||||
#define SET_PEER_XOFF_STATE(X) (bXONOFF[X] |= 0x02)
|
||||
#define SET_PEER_XON_STATE(X) (bXONOFF[X] &= ~(0x02))
|
||||
|
||||
|
||||
static u_char sio_rxd[UART_DEVICE_CNT][MAX_SIO_COUNT];
|
||||
static int sio_head[UART_DEVICE_CNT]; /**< a pointer to serial Rx buffer */
|
||||
static int sio_tail[UART_DEVICE_CNT]; /**< a pointer to serial Rx buffer */
|
||||
static u_char SIO_FLOW[UART_DEVICE_CNT];
|
||||
static u_char bXONOFF[UART_DEVICE_CNT]; /**< XON/XOFF flag bit : 0 bit(1-MY XOFF State, 0-MY XON State), 1 bit(1 - Peer XOFF, 0-Peer XON) */
|
||||
|
||||
static UARTHANDLER uart_handler[UART_DEVICE_CNT];
|
||||
|
||||
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
extern char uart0_getchar(FILE *f);
|
||||
extern void uart0_putchar(char c, FILE *f);
|
||||
#else
|
||||
extern char uart0_getchar(void);
|
||||
extern void uart0_putchar(char c);
|
||||
#endif
|
||||
|
||||
|
||||
#if (__COMPILER_VERSION__ == __WINAVR_20050214__)
|
||||
static void uart0_irq(void);
|
||||
void SIG_UART0_RECV( void ) __attribute__ ((signal));
|
||||
|
||||
void SIG_UART0_RECV( void )
|
||||
{
|
||||
uart0_irq();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ATmega128 UART Rx ISR
|
||||
|
||||
This function is the signal handler for receive complete interrupt.
|
||||
for UART0 Internal Function
|
||||
|
||||
*/
|
||||
static void uart0_irq(void)
|
||||
{
|
||||
sio_rxd[0][sio_head[0]] = UDR0; /* read RX data from UART0 */
|
||||
|
||||
if(SIO_FLOW[0])
|
||||
{
|
||||
if(sio_rxd[0][sio_head[0]] == XOFF_CHAR)
|
||||
SET_PEER_XOFF_STATE(0);
|
||||
else if(sio_rxd[0][sio_head[0]] == XON_CHAR)
|
||||
SET_PEER_XON_STATE(0);
|
||||
else sio_head[0]++;
|
||||
}
|
||||
else sio_head[0]++;
|
||||
|
||||
if (sio_head[0] == sio_tail[0])
|
||||
{
|
||||
if(SIO_FLOW[0])
|
||||
{
|
||||
while (!(UCSR0A & 0x20)) ;
|
||||
UDR0 = XOFF_CHAR;
|
||||
SET_MY_XOFF_STATE(0);
|
||||
}
|
||||
sio_head[0]--; /* buffer full. */
|
||||
}
|
||||
if (sio_head[0] >= MAX_SIO_COUNT) /* for ring buffer */
|
||||
{
|
||||
sio_head[0] = 0;
|
||||
if (sio_head[0] == sio_tail[0]) sio_head[0] = MAX_SIO_COUNT;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/**
|
||||
@brief ATmega128 UART Rx ISR
|
||||
|
||||
This function is the signal handler for receive complete interrupt.
|
||||
for UART0 Internal Function
|
||||
|
||||
*/
|
||||
ISR(USART0_RX_vect) /* Interrupt Service Routine for AVR GCC ver. 3.4.6*/
|
||||
{
|
||||
sio_rxd[0][sio_head[0]] = UDR0; /* read RX data from UART0 */
|
||||
|
||||
if(SIO_FLOW[0])
|
||||
{
|
||||
if(sio_rxd[0][sio_head[0]] == XOFF_CHAR)
|
||||
SET_PEER_XOFF_STATE(0);
|
||||
else if(sio_rxd[0][sio_head[0]] == XON_CHAR)
|
||||
SET_PEER_XON_STATE(0);
|
||||
else sio_head[0]++;
|
||||
}
|
||||
else sio_head[0]++;
|
||||
|
||||
if (sio_head[0] == sio_tail[0])
|
||||
{
|
||||
if(SIO_FLOW[0])
|
||||
{
|
||||
while (!(UCSR0A & 0x20)) ;
|
||||
UDR0 = XOFF_CHAR;
|
||||
SET_MY_XOFF_STATE(0);
|
||||
}
|
||||
sio_head[0]--; /* buffer full. */
|
||||
}
|
||||
if (sio_head[0] >= MAX_SIO_COUNT) /* for ring buffer */
|
||||
{
|
||||
sio_head[0] = 0;
|
||||
if (sio_head[0] == sio_tail[0]) sio_head[0] = MAX_SIO_COUNT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_UART_ONE /* UART1 */
|
||||
|
||||
#if (__COMPILER_VERSION__ == __WINAVR_20050214__)
|
||||
static void uart1_irq(void);
|
||||
void SIG_UART1_RECV( void ) __attribute__ ((signal));
|
||||
|
||||
void SIG_UART1_RECV( void )
|
||||
{
|
||||
uart1_irq();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief ATmega128 UART Rx ISR
|
||||
|
||||
This function is the signal handler for receive complete interrupt.
|
||||
for UART1 Internal Function
|
||||
|
||||
*/
|
||||
static void uart1_irq(void)
|
||||
{
|
||||
sio_rxd[1][sio_head[1]] = UDR1; /* read RX data from UART0 */
|
||||
|
||||
if(SIO_FLOW[1])
|
||||
{
|
||||
if(sio_rxd[1][sio_head[1]] == XOFF_CHAR)
|
||||
SET_PEER_XOFF_STATE(1);
|
||||
else if(sio_rxd[1][sio_head[1]] == XON_CHAR)
|
||||
SET_PEER_XON_STATE(1);
|
||||
else sio_head[1]++;
|
||||
}
|
||||
else sio_head[1]++;
|
||||
|
||||
if (sio_head[1] == sio_tail[1])
|
||||
{
|
||||
if(SIO_FLOW[1])
|
||||
{
|
||||
while (!(UCSR1A & 0x20)) ;
|
||||
UDR1 = XOFF_CHAR;
|
||||
SET_MY_XOFF_STATE(1);
|
||||
}
|
||||
sio_head[1]--; /* buffer full. */
|
||||
}
|
||||
if (sio_head[1] >= MAX_SIO_COUNT) /* for ring buffer */
|
||||
{
|
||||
sio_head[1] = 0;
|
||||
if (sio_head[1] == sio_tail[1]) sio_head[1] = MAX_SIO_COUNT;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/**
|
||||
@brief ATmega128 UART Rx ISR
|
||||
|
||||
This function is the signal handler for receive complete interrupt.
|
||||
for UART1 Internal Function
|
||||
|
||||
*/
|
||||
ISR(USART1_RX_vect) /* Interrupt Service Routine for AVR GCC ver. 3.4.6*/
|
||||
{
|
||||
sio_rxd[1][sio_head[1]] = UDR1; /* read RX data from UART0 */
|
||||
|
||||
if(SIO_FLOW[1])
|
||||
{
|
||||
if(sio_rxd[1][sio_head[1]] == XOFF_CHAR)
|
||||
SET_PEER_XOFF_STATE(1);
|
||||
else if(sio_rxd[1][sio_head[1]] == XON_CHAR)
|
||||
SET_PEER_XON_STATE(1);
|
||||
else sio_head[1]++;
|
||||
}
|
||||
else sio_head[1]++;
|
||||
|
||||
if (sio_head[1] == sio_tail[1])
|
||||
{
|
||||
if(SIO_FLOW[1])
|
||||
{
|
||||
while (!(UCSR1A & 0x20)) ;
|
||||
UDR1 = XOFF_CHAR;
|
||||
SET_MY_XOFF_STATE(1);
|
||||
}
|
||||
sio_head[1]--; /* buffer full. */
|
||||
}
|
||||
if (sio_head[1] >= MAX_SIO_COUNT) /* for ring buffer */
|
||||
{
|
||||
sio_head[1] = 0;
|
||||
if (sio_head[1] == sio_tail[1]) sio_head[1] = MAX_SIO_COUNT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
@brief This function initializes the UART of ATmega64
|
||||
*/
|
||||
void uart_init(
|
||||
u_char uart, /**< UART Device Index(0,1) */
|
||||
u_char baud_index /**< UART BaudRate Index(0:2400,...,11:500000) */
|
||||
)
|
||||
{
|
||||
|
||||
/* enable RxD/TxD and RX INT */
|
||||
u_int uart_select_baud = UART_BAUD_SELECT(baud_index);
|
||||
if(uart == 0) /* uart == 0( first serial ) */
|
||||
{
|
||||
UCSR0B = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
|
||||
|
||||
UBRR0H = (u_char) ((uart_select_baud >> 8) & 0xFF);
|
||||
UBRR0L = (u_char) (uart_select_baud & 0xFF);
|
||||
|
||||
uart_handler[0].uart_get_handler = uart0_getchar;
|
||||
uart_handler[0].uart_put_handler = uart0_putchar;
|
||||
|
||||
#if defined(__STDIO_FDEVOPEN_COMPAT_12)
|
||||
|
||||
/*
|
||||
* Declare prototype for the discontinued version of fdevopen() that
|
||||
* has been in use up to avr-libc 1.2.x. The new implementation has
|
||||
* some backwards compatibility with the old version.
|
||||
*/
|
||||
fdevopen((void *)uart0_putchar, (void *)uart0_getchar, 0);
|
||||
#else /* !defined(__STDIO_FDEVOPEN_COMPAT_12) */
|
||||
/* New prototype for avr-libc 1.4 and above. */
|
||||
|
||||
/* fdevopen((void *)uart0_putchar_avrlibv1_4, (void *)uart0_getchar_avrlibv1_4); */
|
||||
fdevopen((void *)uart0_putchar, (void *)uart0_getchar);
|
||||
#endif /* defined(__STDIO_FDEVOPEN_COMPAT_12) */
|
||||
|
||||
}
|
||||
#ifdef SUPPORT_UART_ONE
|
||||
else if ( uart == 1 )
|
||||
{
|
||||
UCSR1B = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
|
||||
/* set baud rate */
|
||||
UBRR1H = (u_char) ((uart_select_baud >> 8) & 0xFF);
|
||||
UBRR1L = (u_char) (uart_select_baud& 0xFF);
|
||||
|
||||
uart_handler[1].uart_get_handler = uart1_getchar;
|
||||
uart_handler[1].uart_put_handler = uart1_putchar;
|
||||
#if defined(__STDIO_FDEVOPEN_COMPAT_12)
|
||||
|
||||
/*
|
||||
* Declare prototype for the discontinued version of fdevopen() that
|
||||
* has been in use up to avr-libc 1.2.x. The new implementation has
|
||||
* some backwards compatibility with the old version.
|
||||
*/
|
||||
fdevopen((void *)uart1_putchar, (void *)uart1_getchar, 0);
|
||||
#else /* !defined(__STDIO_FDEVOPEN_COMPAT_12) */
|
||||
/* New prototype for avr-libc 1.4 and above. */
|
||||
|
||||
/* fdevopen((void *)uart0_putchar_avrlibv1_4, (void *)uart0_getchar_avrlibv1_4); */
|
||||
fdevopen((void *)uart1_putchar, (void *)uart1_getchar);
|
||||
#endif /* defined(__STDIO_FDEVOPEN_COMPAT_12) */
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
sio_head[uart] = 0;
|
||||
sio_tail[uart] = 0;
|
||||
|
||||
SIO_FLOW[uart] = 0;
|
||||
bXONOFF[uart] = 0;
|
||||
}
|
||||
////---- END_MODIFY
|
||||
|
||||
|
||||
void uart_databit(u_char uart, u_char dbit)
|
||||
{
|
||||
if(uart == 0)
|
||||
{
|
||||
UCSR0C |= 1 << 3;
|
||||
if(!dbit) UCSR0C &= ~(1<<1); // 7bit
|
||||
else UCSR0C |= (1<<1); // 8bit;
|
||||
}
|
||||
#ifdef SUPPORT_UART_ONE
|
||||
else if ( uart == 1 )
|
||||
{
|
||||
UCSR1C |= 1 << 3;
|
||||
if(!dbit) UCSR1C &= ~(1<<1); // 7bit
|
||||
else UCSR1C |= (1<<1); // 8bit;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void uart_stopbit(u_char uart,u_char sbit)
|
||||
{
|
||||
if(uart == 0)
|
||||
{
|
||||
if(!sbit) UCSR0C &= ~(1 << 3); // 1 BIT
|
||||
else UCSR0C |= (1 << 3); // 2 BIT
|
||||
}
|
||||
#ifdef SUPPORT_UART_ONE
|
||||
else if ( uart == 1 )
|
||||
{
|
||||
if(!sbit) UCSR1C &= ~(1 << 3); // 1 BIT
|
||||
else UCSR1C |= (1 << 3); // 2 BIT}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void uart_paritybit(u_char uart,u_char pbit)
|
||||
{
|
||||
if(uart == 0)
|
||||
{
|
||||
if(!pbit) UCSR0C &= ~(3 << 4); // none
|
||||
else if (pbit ==1) UCSR0C &= ~(1 << 4); // even
|
||||
else UCSR0C |= (3 << 4); // odd
|
||||
}
|
||||
#ifdef SUPPORT_UART_ONE
|
||||
else if ( uart == 1 )
|
||||
{
|
||||
if(!pbit) UCSR1C &= ~(3 << 4); // none
|
||||
else if (pbit ==1) UCSR1C &= ~(1 << 4); // even
|
||||
else UCSR1C |= (3 << 4); // odd
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void uart_flowctrl(u_char uart,u_char flow)
|
||||
{
|
||||
if ( uart < UART_DEVICE_CNT )
|
||||
SIO_FLOW[uart] = flow;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief CHECK RX
|
||||
@return retunr RX size, if there is Rx.
|
||||
|
||||
This function checks if there is Rx. \n
|
||||
if not, return 0
|
||||
|
||||
*/
|
||||
u_int uart_keyhit(u_char uart)
|
||||
{
|
||||
if ( uart >= UART_DEVICE_CNT )
|
||||
return 0;
|
||||
|
||||
if(sio_head[uart] >= sio_tail[uart] ) return (sio_head[uart]-sio_tail[uart]);
|
||||
else return (MAX_SIO_COUNT-(sio_tail[uart]-sio_head[uart]));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief WRITE A CHARACTER
|
||||
|
||||
This function sends a character through UART0.
|
||||
|
||||
*/
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
void uart0_putchar(char c, FILE *f)
|
||||
#else
|
||||
void uart0_putchar(char c)
|
||||
#endif
|
||||
{
|
||||
while(SIO_FLOW[0] && (bXONOFF[0] & 0x02)); // If Peer XOFF STATE
|
||||
while (!(UCSR0A & 0x20)) ;
|
||||
UDR0 = c;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief READ A CHARACTER
|
||||
@return c - is a character to read
|
||||
|
||||
This function gets a character from UART0.
|
||||
*/
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
char uart0_getchar(FILE *f)
|
||||
#else
|
||||
char uart0_getchar(void)
|
||||
#endif
|
||||
{
|
||||
char c;
|
||||
while (sio_head[0] == sio_tail[0]);
|
||||
|
||||
c = sio_rxd[0][sio_tail[0]++];
|
||||
|
||||
if(SIO_FLOW[0] && (bXONOFF[0] & 0x01)) // IF MY XOFF STATE
|
||||
{
|
||||
while (!(UCSR0A & 0x20)) ;
|
||||
UDR0 = XON_CHAR;
|
||||
SET_MY_XON_STATE(0);
|
||||
}
|
||||
|
||||
if (sio_tail[0] >= MAX_SIO_COUNT) sio_tail[0] = 0;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_UART_ONE
|
||||
/**
|
||||
@brief WRITE A CHARACTER
|
||||
|
||||
This function sends a character through UART1.
|
||||
|
||||
*/
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
void uart1_putchar(char c, FILE *f)
|
||||
#else
|
||||
void uart1_putchar(char c)
|
||||
#endif
|
||||
{
|
||||
while(SIO_FLOW[1] && (bXONOFF[1] & 0x02)); // If Peer XOFF STATE
|
||||
while (!(UCSR1A & 0x20)) ;
|
||||
UDR1 = c;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief READ A CHARACTER
|
||||
@return c - is a character to read
|
||||
|
||||
This function gets a character from UART1.
|
||||
|
||||
*/
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
char uart1_getchar(FILE *f)
|
||||
#else
|
||||
char uart1_getchar(void)
|
||||
#endif
|
||||
{
|
||||
char c;
|
||||
|
||||
while (sio_head[1] == sio_tail[1]);
|
||||
|
||||
c = sio_rxd[1][sio_tail[1]++];
|
||||
|
||||
if(SIO_FLOW[1] && (bXONOFF[1] & 0x01)) // IF MY XOFF STATE
|
||||
{
|
||||
while (!(UCSR1A & 0x20)) ;
|
||||
UDR1 = XON_CHAR;
|
||||
SET_MY_XON_STATE(1);
|
||||
}
|
||||
|
||||
if (sio_tail[1] >= MAX_SIO_COUNT) sio_tail[1] = 0;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif /* support UART1 */
|
||||
|
||||
|
||||
/**
|
||||
@brief WRITE A CHARACTER
|
||||
|
||||
This function sends a string to UART.
|
||||
|
||||
*/
|
||||
void uart_puts(u_char uart, char * str)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if ( uart >= UART_DEVICE_CNT )
|
||||
return;
|
||||
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
while (str[i]) (*uart_handler[uart].uart_put_handler)(str[i++],NULL);
|
||||
#else
|
||||
while (str[i]) (*uart_handler[uart].uart_put_handler)(str[i++]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief READ A CHARACTER
|
||||
@return str - is a pointer to the string to read
|
||||
|
||||
This function gets a string from UART.
|
||||
|
||||
*/
|
||||
int uart_gets(u_char uart, char * str, char bpasswordtype, int max_len)
|
||||
{
|
||||
char c;
|
||||
char * tsrc = str;
|
||||
char IsFirst = 1;
|
||||
int len = 0;
|
||||
|
||||
if ( uart >= UART_DEVICE_CNT )
|
||||
return 0;
|
||||
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
while ((c = (*uart_handler[uart].uart_get_handler)(NULL)) != 0x0D)
|
||||
#else
|
||||
while ((c = (*uart_handler[uart].uart_get_handler)()) != 0x0D)
|
||||
#endif
|
||||
{
|
||||
if (IsFirst && c=='!')
|
||||
{
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
while(*str != '\0') (*uart_handler[uart].uart_put_handler)(*str++,NULL);
|
||||
#else
|
||||
while(*str != '\0') (*uart_handler[uart].uart_put_handler)(*str++);
|
||||
#endif
|
||||
IsFirst = 0;
|
||||
len++;
|
||||
continue;
|
||||
}
|
||||
if (c == 0x08 && tsrc != str)
|
||||
{
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
(*uart_handler[uart].uart_put_handler)(0x08,NULL);
|
||||
(*uart_handler[uart].uart_put_handler)(' ',NULL);
|
||||
(*uart_handler[uart].uart_put_handler)(0x08,NULL);
|
||||
#else
|
||||
(*uart_handler[uart].uart_put_handler)(0x08);
|
||||
(*uart_handler[uart].uart_put_handler)(' ');
|
||||
(*uart_handler[uart].uart_put_handler)(0x08);
|
||||
#endif
|
||||
str--;
|
||||
len--;
|
||||
continue;
|
||||
}
|
||||
else if (c == 0x1B)
|
||||
{
|
||||
while (tsrc != str)
|
||||
{
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
(*uart_handler[uart].uart_put_handler)(0x08,NULL);
|
||||
(*uart_handler[uart].uart_put_handler)(' ',NULL);
|
||||
(*uart_handler[uart].uart_put_handler)(0x08,NULL);
|
||||
#else
|
||||
(*uart_handler[uart].uart_put_handler)(0x08);
|
||||
(*uart_handler[uart].uart_put_handler)(' ');
|
||||
(*uart_handler[uart].uart_put_handler)(0x08);
|
||||
#endif
|
||||
str--;
|
||||
len--;
|
||||
}
|
||||
IsFirst = 1;
|
||||
continue;
|
||||
}
|
||||
else if ((c < 32 || c > 126) && c != '\t') continue;
|
||||
if(len < max_len)
|
||||
{
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
if(bpasswordtype) (*uart_handler[uart].uart_put_handler)('*',NULL);
|
||||
else (*uart_handler[uart].uart_put_handler)(c,NULL);
|
||||
#else
|
||||
if(bpasswordtype) (*uart_handler[uart].uart_put_handler)('*');
|
||||
else (*uart_handler[uart].uart_put_handler)(c);
|
||||
#endif
|
||||
*str++ = c;
|
||||
len++;
|
||||
IsFirst = 0;
|
||||
}
|
||||
}
|
||||
*str = '\0';
|
||||
uart_puts(uart,"\r\n");
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief GET A BYTE
|
||||
|
||||
This function flush rx buffer of serial
|
||||
|
||||
*/
|
||||
void uart_flush_rx(u_char uart)
|
||||
{
|
||||
if ( uart >= UART_DEVICE_CNT )
|
||||
return;
|
||||
|
||||
sio_head[uart] = sio_tail[uart];
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
*
|
||||
@file serial.h
|
||||
@brief Header file for ATmega64 UART. (AVR-GCC Compiler)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SERIAL_H_
|
||||
#define _SERIAL_H_
|
||||
|
||||
#define MAX_SIO_COUNT 32
|
||||
|
||||
|
||||
#define UART_BAUD_RATE(X) ((X==0) ? 2400 : \
|
||||
(X==1) ? 4800 : \
|
||||
(X==2) ? 9600 : \
|
||||
(X==3) ? 14400 : \
|
||||
(X==4) ? 19200 : \
|
||||
(X==5) ? 28800 : \
|
||||
(X==6) ? 38400 : \
|
||||
(X==7) ? 57600 : \
|
||||
(X==8) ? 76800 : \
|
||||
(X==9) ? 115200 : \
|
||||
(X==10) ? 250000 : \
|
||||
(X==11) ? 500000 : \
|
||||
1000000)
|
||||
|
||||
|
||||
#define UART_BAUD_SELECT(X) (u_int)((float)CLK_CPU/(float)(UART_BAUD_RATE(X)*16) -0.5f)
|
||||
|
||||
|
||||
#define XON_CHAR 0x11
|
||||
#define XOFF_CHAR 0x13
|
||||
|
||||
|
||||
/*
|
||||
********************************************************************************
|
||||
Function Prototype Definition Part
|
||||
********************************************************************************
|
||||
*/
|
||||
extern void uart_init(u_char uart, u_char baud_index); /* Initialize the UART of ATmega64 */
|
||||
|
||||
extern void uart_databit(u_char uart, u_char dbit);
|
||||
|
||||
extern void uart_stopbit(u_char uart, u_char sbit);
|
||||
|
||||
extern void uart_paritybit(u_char uart, u_char pbit);
|
||||
|
||||
extern void uart_flowctrl(u_char uart, u_char flow);
|
||||
|
||||
extern u_int uart_keyhit(u_char uart); /* Check if there is Rx */
|
||||
|
||||
extern void uart_puts(u_char uart, char * str); /* Send a string to UART */
|
||||
extern int uart_gets(u_char uart, char * str,char bpasswordtype, int max_len); /* Get a string from UART */
|
||||
extern void uart_flush_rx(u_char uart); /* Flush RX Buffer */
|
||||
|
||||
|
||||
#endif /* _SERIAL_H_ */
|
||||
|
@ -0,0 +1,181 @@
|
||||
/*
|
||||
*
|
||||
@file type.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TYPE_H_
|
||||
#define _TYPE_H_
|
||||
|
||||
|
||||
/***************************************************
|
||||
* attribute for mcu ( types, ... )
|
||||
***************************************************/
|
||||
//#include "mcu_define.h"
|
||||
#define __MCU_AVR__ 1
|
||||
#define __MCU_TYPE__ __MCU_AVR__
|
||||
|
||||
//---- Refer "Rom File Maker Manual Vx.x.pdf"
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#define _ENDIAN_LITTLE_ 0 /**< This must be defined if system is little-endian alignment */
|
||||
#define _ENDIAN_BIG_ 1
|
||||
#define SYSTEM_ENDIAN _ENDIAN_LITTLE_
|
||||
|
||||
#define MAX_SOCK_NUM 4 /**< Maxmium number of socket */
|
||||
#define CLK_CPU 8000000 /**< 8Mhz(for serial) */
|
||||
|
||||
/* ## __DEF_IINCHIP_xxx__ : define option for iinchip driver *****************/
|
||||
#define __DEF_IINCHIP_DBG__ /* involve debug code in driver (socket.c) */
|
||||
#define __DEF_IINCHIP_INT__ /**< involve interrupt service routine (socket.c) */
|
||||
#define __DEF_IINCHIP_PPP__ /* involve pppoe routine (socket.c) */
|
||||
/* If it is defined, the source files(md5.h,md5.c) must be included in your project.
|
||||
Otherwize, the source files must be removed in your project. */
|
||||
|
||||
#define __DEF_IINCHIP_DIRECT_MODE__ 1
|
||||
#define __DEF_IINCHIP_INDIRECT_MODE__ 2
|
||||
#define __DEF_IINCHIP_SPI_MODE__ 3
|
||||
#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_DIRECT_MODE__
|
||||
//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_INDIRECT_MODE__
|
||||
//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_SPI_MODE__ /*Enable SPI_mode*/
|
||||
|
||||
|
||||
/**
|
||||
@brief __DEF_IINCHIP_MAP_xxx__ : define memory map for iinchip
|
||||
*/
|
||||
#define __DEF_IINCHIP_MAP_BASE__ 0x8000
|
||||
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
|
||||
#define COMMON_BASE __DEF_IINCHIP_MAP_BASE__
|
||||
#else
|
||||
#define COMMON_BASE 0x0000
|
||||
#endif
|
||||
#define __DEF_IINCHIP_MAP_TXBUF__ (COMMON_BASE + 0x4000) /* Internal Tx buffer address of the iinchip */
|
||||
#define __DEF_IINCHIP_MAP_RXBUF__ (COMMON_BASE + 0x6000) /* Internal Rx buffer address of the iinchip */
|
||||
|
||||
|
||||
#if (__MCU_TYPE__ == __MCU_AVR__)
|
||||
#ifdef __DEF_IINCHIP_INT__
|
||||
// iinchip use external interrupt 4
|
||||
#define IINCHIP_ISR_DISABLE() (EIMSK &= ~(0x10))
|
||||
#define IINCHIP_ISR_ENABLE() (EIMSK |= 0x10)
|
||||
#define IINCHIP_ISR_GET(X) (X = EIMSK)
|
||||
#define IINCHIP_ISR_SET(X) (EIMSK = X)
|
||||
#else
|
||||
#define IINCHIP_ISR_DISABLE()
|
||||
#define IINCHIP_ISR_ENABLE()
|
||||
#define IINCHIP_ISR_GET(X)
|
||||
#define IINCHIP_ISR_SET(X)
|
||||
#endif
|
||||
#else
|
||||
#error "unknown MCU type"
|
||||
#endif
|
||||
|
||||
|
||||
/* gcc version */
|
||||
/* WinAVR-20050214-install.exe */
|
||||
#define __WINAVR_20050214__ 0
|
||||
#define __WINAVR_20060125__ 1
|
||||
#define __WINAVR_20060421__ 2
|
||||
|
||||
/* #define __COMPILER_VERSION__ __WINAVR_20060421__ // <- move makefile*/
|
||||
|
||||
#if (__COMPILER_VERSION__ == __WINAVR_20050214__)
|
||||
#ifndef __STDIO_FDEVOPEN_COMPAT_12
|
||||
#define __STDIO_FDEVOPEN_COMPAT_12
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *) 0)
|
||||
#endif
|
||||
|
||||
typedef enum { false, true } bool;
|
||||
|
||||
#ifndef _SIZE_T
|
||||
#define _SIZE_T
|
||||
typedef unsigned int size_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The 8-bit signed data type.
|
||||
*/
|
||||
typedef char int8;
|
||||
/**
|
||||
* The volatile 8-bit signed data type.
|
||||
*/
|
||||
typedef volatile char vint8;
|
||||
/**
|
||||
* The 8-bit unsigned data type.
|
||||
*/
|
||||
typedef unsigned char uint8;
|
||||
/**
|
||||
* The volatile 8-bit unsigned data type.
|
||||
*/
|
||||
typedef volatile unsigned char vuint8;
|
||||
|
||||
/**
|
||||
* The 16-bit signed data type.
|
||||
*/
|
||||
typedef int int16;
|
||||
/**
|
||||
* The volatile 16-bit signed data type.
|
||||
*/
|
||||
typedef volatile int vint16;
|
||||
/**
|
||||
* The 16-bit unsigned data type.
|
||||
*/
|
||||
typedef unsigned int uint16;
|
||||
/**
|
||||
* The volatile 16-bit unsigned data type.
|
||||
*/
|
||||
typedef volatile unsigned int vuint16;
|
||||
/**
|
||||
* The 32-bit signed data type.
|
||||
*/
|
||||
typedef long int32;
|
||||
/**
|
||||
* The volatile 32-bit signed data type.
|
||||
*/
|
||||
typedef volatile long vint32;
|
||||
/**
|
||||
* The 32-bit unsigned data type.
|
||||
*/
|
||||
typedef unsigned long uint32;
|
||||
/**
|
||||
* The volatile 32-bit unsigned data type.
|
||||
*/
|
||||
typedef volatile unsigned long vuint32;
|
||||
|
||||
/* bsd */
|
||||
typedef uint8 u_char; /**< 8-bit value */
|
||||
typedef uint8 SOCKET;
|
||||
typedef uint16 u_short; /**< 16-bit value */
|
||||
typedef uint16 u_int; /**< 16-bit value */
|
||||
typedef uint32 u_long; /**< 32-bit value */
|
||||
|
||||
typedef union _un_l2cval {
|
||||
u_long lVal;
|
||||
u_char cVal[4];
|
||||
}un_l2cval;
|
||||
|
||||
typedef union _un_i2cval {
|
||||
u_int iVal;
|
||||
u_char cVal[2];
|
||||
}un_i2cval;
|
||||
|
||||
|
||||
/** global define */
|
||||
#define FW_VERSION 0x01000001 /**< System F/W Version(test) : 0.0.0.1 */
|
||||
#define HW_PM_VERSION "0.1"
|
||||
#define HW_NM_VERSION "0.1"
|
||||
#define HW_MB_VERSION "0.1"
|
||||
|
||||
|
||||
#define TX_RX_MAX_BUF_SIZE 2048
|
||||
#define TX_BUF 0x1100
|
||||
#define RX_BUF (TX_BUF+TX_RX_MAX_BUF_SIZE)
|
||||
|
||||
#define UART_DEVICE_CNT 1 /**< UART device number */
|
||||
/* #define SUPPORT_UART_ONE */
|
||||
|
||||
#endif /* _TYPE_H_ */
|
@ -0,0 +1,180 @@
|
||||
/**
|
||||
@file myprintf.h
|
||||
*/
|
||||
|
||||
#ifndef __MYPRINTF_H
|
||||
#define __MYPRINTF_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
//#define DEBUG_MODE
|
||||
|
||||
#define PRINT(x) ( \
|
||||
{ \
|
||||
static prog_char str[] = x; \
|
||||
printf_P(str); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define PRINT1(x,arg1) ( \
|
||||
{ \
|
||||
static prog_char str[] = x; \
|
||||
printf_P(str,arg1); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define PRINT2(x,arg1,arg2) ( \
|
||||
{ \
|
||||
static prog_char str[] = x; \
|
||||
printf_P(str,arg1,arg2); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define PRINT3(x,arg1,arg2,arg3) ( \
|
||||
{ \
|
||||
static prog_char str[] = x; \
|
||||
printf_P(str,arg1,arg2,arg3); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define PRINT4(x,arg1,arg2,arg3,arg4) ( \
|
||||
{ \
|
||||
static prog_char str[] = x; \
|
||||
printf_P(str,arg1,arg2,arg3,arg4); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define PRINTLN(x) ( \
|
||||
{ \
|
||||
static prog_char str[] = x"\r\n"; \
|
||||
printf_P(str); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define PRINTLN1(x,arg1) ( \
|
||||
{ \
|
||||
static prog_char str[] = x"\r\n"; \
|
||||
printf_P(str,arg1); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define PRINTLN2(x,arg1,arg2) ( \
|
||||
{ \
|
||||
static prog_char str[] = x"\r\n"; \
|
||||
printf_P(str,arg1,arg2); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define PRINTLN3(x,arg1,arg2,arg3) ( \
|
||||
{ \
|
||||
static prog_char str[] = x"\r\n"; \
|
||||
printf_P(str,arg1,arg2,arg3); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define PRINTLN4(x,arg1,arg2,arg3,arg4) ( \
|
||||
{ \
|
||||
static prog_char str[] = x"\r\n"; \
|
||||
printf_P(str,arg1,arg2,arg3,arg4); \
|
||||
} \
|
||||
)
|
||||
|
||||
#ifdef DEBUG_MODE
|
||||
|
||||
#define DPRINT(x) ( \
|
||||
{ \
|
||||
static prog_char str[] = x; \
|
||||
printf_P(str); \
|
||||
} \
|
||||
)
|
||||
|
||||
|
||||
#define DPRINT1(x,arg1) ( \
|
||||
{ \
|
||||
static prog_char str[] = x; \
|
||||
printf_P(str,arg1); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define DPRINT2(x,arg1,arg2) ( \
|
||||
{ \
|
||||
static prog_char str[] = x; \
|
||||
printf_P(str,arg1,arg2); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define DPRINT3(x,arg1,arg2,arg3) ( \
|
||||
{ \
|
||||
static prog_char str[] = x; \
|
||||
printf_P(str,arg1,arg2,arg3); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define DPRINT4(x,arg1,arg2,arg3,arg4) ( \
|
||||
{ \
|
||||
static prog_char str[] = x; \
|
||||
printf_P(str,arg1,arg2,arg3,arg4); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define DPRINTLN(x) ( \
|
||||
{ \
|
||||
static prog_char str[] = x"\r\n"; \
|
||||
printf_P(str); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define DPRINTLN1(x,arg1) ( \
|
||||
{ \
|
||||
static prog_char str[] = x"\r\n"; \
|
||||
printf_P(str,arg1); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define DPRINTLN2(x,arg1,arg2) ( \
|
||||
{ \
|
||||
static prog_char str[] = x"\r\n"; \
|
||||
printf_P(str,arg1,arg2); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define DPRINTLN3(x,arg1,arg2,arg3) ( \
|
||||
{ \
|
||||
static prog_char str[] = x"\r\n"; \
|
||||
printf_P(str,arg1,arg2,arg3); \
|
||||
} \
|
||||
)
|
||||
|
||||
#define DPRINTLN4(x,arg1,arg2,arg3,arg4) ( \
|
||||
{ \
|
||||
static prog_char str[] = x"\r\n"; \
|
||||
printf_P(str,arg1,arg2,arg3,arg4); \
|
||||
} \
|
||||
)
|
||||
|
||||
#else
|
||||
|
||||
#define DPRINT(x) ({})
|
||||
|
||||
#define DPRINT1(x,arg1) ({})
|
||||
|
||||
#define DPRINT2(x,arg1,arg2) ({})
|
||||
|
||||
#define DPRINT3(x,arg1,arg2,arg3) ({})
|
||||
|
||||
#define DPRINT4(x,arg1,arg2,arg3,arg4) ({})
|
||||
|
||||
#define DPRINTLN(x) ({})
|
||||
|
||||
#define DPRINTLN1(x,arg1) ({})
|
||||
|
||||
#define DPRINTLN2(x,arg1,arg2) ({})
|
||||
|
||||
#define DPRINTLN3(x,arg1,arg2,arg3) ({})
|
||||
|
||||
#define DPRINTLN4(x,arg1,arg2,arg3,arg4) ({})
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,372 @@
|
||||
/*
|
||||
*
|
||||
@file sockutil.c
|
||||
@brief Implementation of useful function of iinChip
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
//#include "serial.h"
|
||||
//#include "myprintf.h"
|
||||
#include "util.h"
|
||||
//#include "config.h"
|
||||
#include "w5100.h"
|
||||
#include "sockutil.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@brief Convert 32bit Address(Host Ordering) into Dotted Decimal Format
|
||||
@return a char pointer to a static buffer containing the text address in standard ".'' notation. Otherwise, it returns NULL.
|
||||
*/
|
||||
char* inet_ntoa(
|
||||
unsigned long addr /**< Pointer variable to store converted value(INPUT) */
|
||||
)
|
||||
{
|
||||
static char addr_str[16];
|
||||
memset(addr_str,0,16);
|
||||
sprintf(addr_str,"%d.%d.%d.%d",(int)(addr>>24 & 0xFF),(int)(addr>>16 & 0xFF),(int)(addr>>8 & 0xFF),(int)(addr & 0xFF));
|
||||
return addr_str;
|
||||
}
|
||||
|
||||
#if 0
|
||||
char* inet_ntoa_pad(unsigned long addr)
|
||||
{
|
||||
static char addr_str[16];
|
||||
memset(addr_str,0,16);
|
||||
sprintf(addr_str,"%03d.%03d.%03d.%03d",(int)(addr>>24 & 0xFF),(int)(addr>>16 & 0xFF),(int)(addr>>8 & 0xFF),(int)(addr & 0xFF));
|
||||
return addr_str;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
@brief Converts a string containing an (Ipv4) Internet Protocol decimal dotted address into a 32bit address
|
||||
@return 32bit address (Host Odering)
|
||||
*/
|
||||
unsigned long inet_addr(
|
||||
unsigned char* addr /**< dotted notation address string. */
|
||||
)
|
||||
{
|
||||
char i;
|
||||
u_long inetaddr = 0;
|
||||
char taddr[30];
|
||||
char * nexttok;
|
||||
int num;
|
||||
strcpy(taddr,addr);
|
||||
|
||||
nexttok = taddr;
|
||||
for(i = 0; i < 4 ; i++)
|
||||
{
|
||||
nexttok = strtok(nexttok,".");
|
||||
if(nexttok[0] == '0' && nexttok[1] == 'x') num = ATOI(nexttok+2,0x10);
|
||||
else num = ATOI(nexttok,10);
|
||||
inetaddr = inetaddr << 8;
|
||||
inetaddr |= (num & 0xFF);
|
||||
nexttok = NULL;
|
||||
}
|
||||
return inetaddr;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
@brief Verify dotted notation IP address string
|
||||
@return success - 1, fail - 0
|
||||
*/
|
||||
char VerifyIPAddress(
|
||||
char* src /**< pointer to IP address string */
|
||||
)
|
||||
{
|
||||
int i;
|
||||
int tnum;
|
||||
char tsrc[50];
|
||||
char* tok = tsrc;
|
||||
|
||||
strcpy(tsrc,src);
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
tok = strtok(tok,".");
|
||||
if ( !tok ) return 0;
|
||||
if(tok[0] == '0' && tok[1] == 'x')
|
||||
{
|
||||
if(!ValidATOI(tok+2,0x10,&tnum)) return 0;
|
||||
}
|
||||
else if(!ValidATOI(tok,10,&tnum)) return 0;
|
||||
|
||||
if(tnum < 0 || tnum > 255) return 0;
|
||||
tok = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Output destination IP address of appropriate channel
|
||||
@return 32bit destination address (Host Ordering)
|
||||
*/
|
||||
unsigned long GetDestAddr(
|
||||
SOCKET s /**< Channel number which try to get destination IP Address */
|
||||
)
|
||||
{
|
||||
u_long addr=0;
|
||||
int i = 0;
|
||||
for(i=0; i < 4; i++)
|
||||
{
|
||||
addr <<=8;
|
||||
addr += IINCHIP_READ(Sn_DIPR0(s)+i);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Output destination port number of appropriate channel
|
||||
@return 16bit destination port number
|
||||
*/
|
||||
unsigned int GetDestPort(
|
||||
SOCKET s /**< Channel number which try to get destination port */
|
||||
)
|
||||
{
|
||||
u_int port;
|
||||
port = ((u_int) IINCHIP_READ(Sn_DPORT0(s))) & 0x00FF;
|
||||
port <<= 8;
|
||||
port += ((u_int) IINCHIP_READ(Sn_DPORT0(s)+1)) & 0x00FF;
|
||||
return port;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
@brief htons function converts a unsigned short from host to TCP/IP network byte order (which is big-endian).
|
||||
@return the value in TCP/IP network byte order
|
||||
*/
|
||||
unsigned short htons(
|
||||
unsigned short hostshort /**< A 16-bit number in host byte order. */
|
||||
)
|
||||
{
|
||||
#if ( SYSTEM_ENDIAN == _ENDIAN_LITTLE_ )
|
||||
return swaps(hostshort);
|
||||
#else
|
||||
return hostshort;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief htonl function converts a unsigned long from host to TCP/IP network byte order (which is big-endian).
|
||||
@return the value in TCP/IP network byte order
|
||||
*/
|
||||
unsigned long htonl(
|
||||
unsigned long hostlong /**< hostshort - A 32-bit number in host byte order. */
|
||||
)
|
||||
{
|
||||
#if ( SYSTEM_ENDIAN == _ENDIAN_LITTLE_ )
|
||||
return swapl(hostlong);
|
||||
#else
|
||||
return hostlong;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief ntohs function converts a unsigned short from TCP/IP network byte order to host byte order (which is little-endian on Intel processors).
|
||||
@return a 16-bit number in host byte order
|
||||
*/
|
||||
unsigned long ntohs(
|
||||
unsigned short netshort /**< netshort - network odering 16bit value */
|
||||
)
|
||||
{
|
||||
#if ( SYSTEM_ENDIAN == _ENDIAN_LITTLE_ )
|
||||
return htons(netshort);
|
||||
#else
|
||||
return netshort;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief converts a unsigned long from TCP/IP network byte order to host byte order (which is little-endian on Intel processors).
|
||||
@return a 16-bit number in host byte order
|
||||
*/
|
||||
unsigned long ntohl(unsigned long netlong)
|
||||
{
|
||||
#if ( SYSTEM_ENDIAN == _ENDIAN_LITTLE_ )
|
||||
return htonl(netlong);
|
||||
#else
|
||||
return netlong;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
// destip : BigEndian
|
||||
u_char CheckDestInLocal(u_long destip)
|
||||
{
|
||||
int i = 0;
|
||||
u_char * pdestip = (u_char*)&destip;
|
||||
for(i =0; i < 4; i++)
|
||||
{
|
||||
if((pdestip[i] & IINCHIP_READ(SUBR0+i)) != (IINCHIP_READ(SIPR0+i) & IINCHIP_READ(SUBR0+i)))
|
||||
return 1; // Remote
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
@brief Get handle of socket which status is same to 'status'
|
||||
@return socket number
|
||||
*/
|
||||
SOCKET getSocket(
|
||||
unsigned char status, /**< socket's status to be found */
|
||||
SOCKET start /**< base of socket to be found */
|
||||
)
|
||||
{
|
||||
SOCKET i;
|
||||
if(start > 3) start = 0;
|
||||
|
||||
for(i = start; i < MAX_SOCK_NUM ; i++) if( getSn_SR(i)==status ) return i;
|
||||
return MAX_SOCK_NUM;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
@brief Calculate checksum of a stream
|
||||
@return checksum
|
||||
*/
|
||||
unsigned short checksum(
|
||||
unsigned char * src, /**< pointer to stream */
|
||||
unsigned int len /**< size of stream */
|
||||
)
|
||||
{
|
||||
u_int sum, tsum, i, j;
|
||||
u_long lsum;
|
||||
|
||||
j = len >> 1;
|
||||
|
||||
lsum = 0;
|
||||
|
||||
for (i = 0; i < j; i++)
|
||||
{
|
||||
tsum = src[i * 2];
|
||||
tsum = tsum << 8;
|
||||
tsum += src[i * 2 + 1];
|
||||
lsum += tsum;
|
||||
}
|
||||
|
||||
if (len % 2)
|
||||
{
|
||||
tsum = src[i * 2];
|
||||
lsum += (tsum << 8);
|
||||
}
|
||||
|
||||
|
||||
sum = lsum;
|
||||
sum = ~(sum + (lsum >> 16));
|
||||
return (u_short) sum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef NO_USE_SOCKUTIL_FUNC
|
||||
/**
|
||||
@brief Get Source IP Address of iinChip.
|
||||
@return Source IP Address(32bit Address-Host Ordering)
|
||||
*/
|
||||
u_long GetIPAddress(void)
|
||||
{
|
||||
u_long ip=0;
|
||||
int i;
|
||||
for(i=0; i < 4; i++)
|
||||
{
|
||||
ip <<= 8;
|
||||
ip += (char)IINCHIP_READ(SIPR0+i);
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Get Gateway IP Address of iinChip.
|
||||
@return Gateway IP Address(32bit Address-Host Ordering)
|
||||
*/
|
||||
u_long GetGWAddress(void)
|
||||
{
|
||||
u_long ip=0;
|
||||
int i;
|
||||
for(i=0; i < 4; i++)
|
||||
{
|
||||
ip <<= 8;
|
||||
ip += (char)IINCHIP_READ(GAR0+i);
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Get Subnet mask of iinChip.
|
||||
@return Subnet Mask(32bit Address-Host Ordering)
|
||||
*/
|
||||
u_long GetSubMask(void)
|
||||
{
|
||||
u_long ip=0;
|
||||
int i;
|
||||
for(i=0; i < 4; i++)
|
||||
{
|
||||
ip <<= 8;
|
||||
ip += (char)IINCHIP_READ(SUBR0+i);
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Get Mac Address of iinChip.
|
||||
@return Subnet Mask(32bit Address-Host Ordering)
|
||||
*/
|
||||
void GetMacAddress(
|
||||
unsigned char* mac /**< Pointer to store Mac Address(48bit Address)(INPUT, OUTPUT) */
|
||||
)
|
||||
{
|
||||
int i = 0;
|
||||
for(i=0; i<6;i++)*mac++ = IINCHIP_READ(SHAR0+i);
|
||||
}
|
||||
|
||||
void GetDestMacAddr(SOCKET s, u_char* mac)
|
||||
{
|
||||
int i = 0;
|
||||
for(i=0; i<6;i++)*mac++ = IINCHIP_READ(Sn_DHAR0(s)+i);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Read established network information(G/W, IP, S/N, Mac) of iinChip and Output that through Serial.
|
||||
Mac Address is output into format of Dotted HexaDecimal.Others are output into format of Dotted Decimal Format.
|
||||
*/
|
||||
void GetNetConfig(void)
|
||||
{
|
||||
u_char addr[6];
|
||||
u_long iaddr;
|
||||
printf("\r\n================================================\r\n");
|
||||
printf(" Net Config Information\r\n");
|
||||
printf("================================================\r\n");
|
||||
GetMacAddress(addr);
|
||||
printf("MAC ADDRESS : 0x%02X.0x%02X.0x%02X.0x%02X.0x%02X.0x%02X\r\n",addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]);
|
||||
|
||||
iaddr = GetSubMask();
|
||||
printf("SUBNET MASK : %s\r\n",inet_ntoa(iaddr));
|
||||
|
||||
iaddr = GetGWAddress();
|
||||
printf("G/W IP ADDRESS : %s\r\n",inet_ntoa(iaddr));
|
||||
|
||||
iaddr = GetIPAddress();
|
||||
printf("LOCAL IP ADDRESS : %s\r\n",inet_ntoa(iaddr));
|
||||
printf("================================================\r\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
*
|
||||
@file sockutil.h
|
||||
@brief Implementation of useful function of iinChip
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SOCKUTIL_H
|
||||
#define __SOCKUTIL_H
|
||||
|
||||
|
||||
#define NO_USE_SOCKUTIL_FUNC
|
||||
|
||||
extern char* inet_ntoa(unsigned long addr); /* Convert 32bit Address into Dotted Decimal Format */
|
||||
extern unsigned long inet_addr(unsigned char* addr); /* Converts a string containing an (Ipv4) Internet Protocol decimal dotted address into a 32bit address */
|
||||
|
||||
#if 0
|
||||
extern char* inet_ntoa_pad(unsigned long addr);
|
||||
|
||||
|
||||
extern char VerifyIPAddress(char* src); /* Verify dotted notation IP address string */
|
||||
|
||||
extern unsigned long GetDestAddr(SOCKET s); /* Output destination IP address of appropriate channel */
|
||||
|
||||
extern unsigned int GetDestPort(SOCKET s); /* Output destination port number of appropriate channel */
|
||||
#endif
|
||||
|
||||
extern unsigned short htons( unsigned short hostshort); /* htons function converts a unsigned short from host to TCP/IP network byte order (which is big-endian).*/
|
||||
|
||||
extern unsigned long htonl(unsigned long hostlong); /* htonl function converts a unsigned long from host to TCP/IP network byte order (which is big-endian). */
|
||||
|
||||
extern unsigned long ntohs(unsigned short netshort); /* ntohs function converts a unsigned short from TCP/IP network byte order to host byte order (which is little-endian on Intel processors). */
|
||||
|
||||
extern unsigned long ntohl(unsigned long netlong); /* ntohl function converts a u_long from TCP/IP network order to host byte order (which is little-endian on Intel processors). */
|
||||
|
||||
extern SOCKET getSocket(unsigned char status, SOCKET start); /* Get handle of socket which status is same to 'status' */
|
||||
|
||||
#if 0
|
||||
extern u_char CheckDestInLocal(u_long destip); /* Check Destination in local or remote */
|
||||
|
||||
extern unsigned short checksum(unsigned char * src, unsigned int len); /* Calculate checksum of a stream */
|
||||
|
||||
#ifndef NO_USE_SOCKUTIL_FUNC
|
||||
|
||||
extern u_long GetIPAddress(void); /* Get Source IP Address of iinChip. */
|
||||
|
||||
extern u_long GetGWAddress(void); /* Get Source IP Address of iinChip. */
|
||||
|
||||
extern u_long GetSubMask(void); /* Get Source Subnet mask of iinChip. */
|
||||
|
||||
extern void GetMacAddress(unsigned char* mac); /* Get Mac address of iinChip. */
|
||||
|
||||
extern void GetDestMacAddr(SOCKET s, u_char* mac);
|
||||
|
||||
extern void GetNetConfig(void); /* Read established network information(G/W, IP, S/N, Mac) of iinChip and Output that through Serial.*/
|
||||
|
||||
extern void dump_iinchip(void); /* dump the 4 channel status of iinChip */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,239 @@
|
||||
/*
|
||||
*
|
||||
@file util.c
|
||||
@brief The utility functions for AVREVB. (AVR-GCC Compiler)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
static char * ___strtok=NULL;
|
||||
|
||||
|
||||
/**
|
||||
@brief CONVERT HEX INTO CHAR
|
||||
@return a character
|
||||
|
||||
This function converts HEX(0-F) to a character
|
||||
*/
|
||||
u_char D2C(
|
||||
char c /**< is a Hex(0x00~0x0F) to convert to a character */
|
||||
)
|
||||
{
|
||||
u_int t = (u_int) c;
|
||||
if (t >= 0 && t <= 9)
|
||||
return '0' + c;
|
||||
if (t >= 10 && t <= 15)
|
||||
return 'A' + c - 10;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief CONVERT CHAR INTO HEX
|
||||
@return HEX
|
||||
|
||||
This function converts HEX(0-F) to a character
|
||||
*/
|
||||
char C2D(
|
||||
u_char c /**< is a character('0'-'F') to convert to HEX */
|
||||
)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return 10 + c -'a';
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return 10 + c -'A';
|
||||
|
||||
return (char)c;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief CONVERT STRING INTO INTEGER
|
||||
@return a integer number
|
||||
*/
|
||||
u_int ATOI(
|
||||
char* str, /**< is a pointer to convert */
|
||||
u_int base /**< is a base value (must be in the range 2 - 16) */
|
||||
)
|
||||
{
|
||||
unsigned int num = 0;
|
||||
while (*str !=0)
|
||||
num = num * base + C2D(*str++);
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief CONVERT STRING INTO HEX OR DECIMAL
|
||||
@return success - 1, fail - 0
|
||||
*/
|
||||
int ValidATOI(
|
||||
char* str, /**< is a pointer to string to be converted */
|
||||
int base, /**< is a base value (must be in the range 2 - 16) */
|
||||
int* ret /**< is a integer pointer to return */
|
||||
)
|
||||
{
|
||||
int c;
|
||||
char* tstr = str;
|
||||
if(str == 0 || *str == '\0') return 0;
|
||||
while(*tstr != '\0')
|
||||
{
|
||||
c = C2D(*tstr);
|
||||
if( c >= 0 && c < base) tstr++;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
*ret = ATOI(str,base);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Calculate the length of the initial substring of "s" which only contain letters in "accept"
|
||||
@return The string to search for
|
||||
*/
|
||||
size_t strspn(
|
||||
const char *s, /**< The string to be searched */
|
||||
const char *accept /**< The string to search for */
|
||||
)
|
||||
{
|
||||
const char *p;
|
||||
const char *a;
|
||||
size_t count = 0;
|
||||
|
||||
for (p = s; *p != '\0'; ++p) {
|
||||
for (a = accept; *a != '\0'; ++a) {
|
||||
if (*p == *a)
|
||||
break;
|
||||
}
|
||||
if (*a == '\0')
|
||||
return count;
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Find the first occurrence of a set of characters
|
||||
*/
|
||||
char * strpbrk(
|
||||
const char * cs, /**< The string to be searched */
|
||||
const char * ct /**< The characters to search for */
|
||||
)
|
||||
{
|
||||
const char *sc1,*sc2;
|
||||
|
||||
for( sc1 = cs; *sc1 != '\0'; ++sc1) {
|
||||
for( sc2 = ct; *sc2 != '\0'; ++sc2) {
|
||||
if (*sc1 == *sc2)
|
||||
return (char *) sc1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Split a string into tokens
|
||||
|
||||
WARNING: strtok is deprecated, use strsep instead.
|
||||
*/
|
||||
char * strtok(
|
||||
char * s, /**< The string to be searched */
|
||||
const char * ct /**< The characters to search for */
|
||||
)
|
||||
{
|
||||
char *sbegin, *send;
|
||||
|
||||
sbegin = s ? s : ___strtok;
|
||||
if (!sbegin) {
|
||||
return NULL;
|
||||
}
|
||||
sbegin += strspn(sbegin,ct);
|
||||
if (*sbegin == '\0') {
|
||||
___strtok = NULL;
|
||||
return( NULL );
|
||||
}
|
||||
send = strpbrk( sbegin, ct);
|
||||
if (send && *send != '\0')
|
||||
*send++ = '\0';
|
||||
___strtok = send;
|
||||
return (sbegin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@brief replace the specified character in a string with new character
|
||||
*/
|
||||
void replacetochar(
|
||||
char * str, /**< pointer to be replaced */
|
||||
char oldchar, /**< old character */
|
||||
char newchar /**< new character */
|
||||
)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; str[x]; x++)
|
||||
if (str[x] == oldchar) str[x] = newchar;
|
||||
}
|
||||
|
||||
|
||||
u_short swaps(u_int i)
|
||||
{
|
||||
u_short ret=0;
|
||||
ret = (i & 0xFF) << 8;
|
||||
ret |= ((i >> 8)& 0xFF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u_long swapl(u_long l)
|
||||
{
|
||||
u_long ret=0;
|
||||
ret = (l & 0xFF) << 24;
|
||||
ret |= ((l >> 8) & 0xFF) << 16;
|
||||
ret |= ((l >> 16) & 0xFF) << 8;
|
||||
ret |= ((l >> 24) & 0xFF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef NO_USE_UTIL_FUNC
|
||||
/**
|
||||
@brief This function converts a integer number to a string.
|
||||
@return a pointer to string
|
||||
*/
|
||||
char* ITOA(
|
||||
u_int value, /**< is a integer value to be converted */
|
||||
char* str, /**< is a pointer to string to be returned */
|
||||
u_int base /**< is a base value (must be in the range 2 - 16) */
|
||||
)
|
||||
{
|
||||
char c;
|
||||
char* tstr = str;
|
||||
char* ret = str;
|
||||
if(value == 0) *str++='0';
|
||||
while(value > 0)
|
||||
{
|
||||
*str++ =(char)D2C((char)(value%base));
|
||||
value /= base;
|
||||
}
|
||||
*str-- ='\0';
|
||||
while(tstr < str )
|
||||
{
|
||||
c = *tstr;
|
||||
*tstr++ = *str;
|
||||
*str-- = c;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
*
|
||||
@file util.h
|
||||
*/
|
||||
|
||||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
|
||||
#define NO_USE_UTIL_FUNC
|
||||
|
||||
|
||||
extern u_char D2C(char c); /* Convert HEX(0-F) to a character */
|
||||
extern char C2D(u_char c); /* Convert a character to HEX */
|
||||
extern u_int ATOI(char* str,u_int base); /* Convert a string to integer number */
|
||||
extern int ValidATOI(char* str, int base, int* ret); /* Verify character string and Convert it to (hexa-)decimal. */
|
||||
extern char * strtok(char * s,const char * ct); /* Tokenize a string */
|
||||
extern void replacetochar(char * str, char oldchar, char newchar); /* Replace old character with new character in the string */
|
||||
|
||||
|
||||
extern u_short swaps(u_int i);
|
||||
extern u_long swapl(u_long l);
|
||||
|
||||
|
||||
#ifndef NO_USE_UTIL_FUNC
|
||||
extern char* ITOA(u_int value,char* str,u_int base); /* Convert Decimal Number to string */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _UTIL_H */
|
||||
|
Loading…
Reference in new issue