|
The blue Plop Clock (year 2006)IntroductionThis clock is showing the time with blue colored led's. The Clock can request the time from my network. A relais is connected to the clock and can be controlled from any computer in my network (ex. turn a lamp on or off). Why i build a blue clock? Simply, I wanted to have a blue clock. The clocks is running with an Atmel processor connected with the Wilke EM01-ETH-S network modul. The display is a dotmatrix led display (3 in a row). The firmware is written in assembler. Photo/Video
Wilke EM-01 Network routinesI release my network routines for the network module EM-01 from Wilke to use it with a Atmel ATMEGA16 processor in Assembler under the Terms of the GPLv2.
Overview:
You can connect to the Atmel with telnet. Info: No default Gateway is set. So the program will work only in your local network.
File: eth/eth.asm
;**********************************************************************
;
; Copyright (C) 2007-2008 Elmar Hanlhofer http://www.plop.at
;;
;**********************************************************************
.include "m16def.inc"
;=====================================================================
; PLoP ETH v1.2 20080628
.equ TEST = 1
.equ EM01_PORT = PORTC
.equ EM01_PIN = PINC
.equ EM01_DDR = DDRC
.equ EM01_BAUD0 = PC0
.equ EM01_BAUD1 = PC1
.equ EM01_BAUD2 = PC2
.equ EM01_CTS = PC3
.equ EM01_RTS = PC4
.equ EM01_RESET = PC5
.include "em01/em01const.asm"
;.equ UBRRVAL = 12 ; 19200 baud @ 4mhz
.equ UBRRVAL = 25 ; 19200 baud @ 8mhz
.org 0x0 ; reset vector
rjmp reset
.org 0x13
reset: ; reset subprocedure
ldi r16, low(RAMEND) ; init stack to point to RAMEND
out SPL, r16
ldi r16, high(RAMEND)
out SPH, r16
;--------------------------
; setup ports to em01
;--------------------------
ldi r16,1 << EM01_RTS | 1 << PC7 | 1 << PC6
out EM01_PORT,r16
com r16
out EM01_DDR,r16
sei
;--------------------------
; setup usart and em01
;--------------------------
rcall initUSART
rcall initEM01
;--------------------------
; wait until em01 accepts data
;--------------------------
rcall em01Wait
ldi r16,1
sts init,r16
;--------------------------
; accept data from em01
;--------------------------
cbi EM01_PORT,EM01_CTS
rcall initNetwork
;================================================================
; mainloop
;================================================================
_main:
rcall mainLoop
rjmp _main
;================================================================
mainLoop:
lds r16,init
cpi r16,1
breq _main3
;--------------------------
; accept no data from em01
;--------------------------
sbi EM01_PORT,EM01_CTS
; do something
;--------------------------
; accept data from em01
;--------------------------
cbi EM01_PORT,EM01_CTS
_main3:
;--------------------------
; wait for data from em01
;--------------------------
sbis UCSRA,RXC
rjmp mainLoop
rcall em01ReceiveBuffer
rcall handleEM01Response
ret
;================================================================
; functions
;================================================================
;----------------------------------
; setup usart
;----------------------------------
initUSART:
;--------------------------
; setup baud
;--------------------------
ldi r16,LOW(UBRRVAL)
out UBRRL,r16
ldi r16,HIGH(UBRRVAL)
out UBRRH,r16
ldi r16,(1 << RXEN)|(1 << TXEN)
out UCSRB,r16
;--------------------------
; Frame-Format: 8 Bit, 0 parity, 1 stop bit
;--------------------------
ldi r16, (1 << URSEL)|(3 << UCSZ0)
out UCSRC,r16
ret
;----------------------------------
; reset em01 and set baud
;----------------------------------
initEM01:
;--------------------------
; baud 19200
;--------------------------
sbi EM01_PORT,EM01_BAUD0
cbi EM01_PORT,EM01_BAUD1
sbi EM01_PORT,EM01_BAUD2
;--------------------------
;reset EM01 device
;--------------------------
cbi EM01_PORT,EM01_RESET
ldi r16,20
_initEM01:
dec r16
brne _initEM01
;--------------------------
; reset end
;--------------------------
sbi EM01_PORT,EM01_RESET
;--------------------------
; accept data from em01
;--------------------------
cbi EM01_PORT,EM01_CTS
ret
;----------------------------------
; setup em01 ip to 10.0.0.12/255.255.255.0
; setup one tcp socket for a connection to a server
; setup one tcp socket for connecting a client to em01 on port 25
;----------------------------------
initNetwork:
rcall netUnsetSocketConnect
rcall netUnsetSocketListen
rcall netUnsetSocketAccept
;--------------------------
; set ip address
;--------------------------
ldi r16,10
sts eth_ip+0,r16
ldi r16,0
sts eth_ip+1,r16
ldi r16,0
sts eth_ip+2,r16
.IF TEST = 1
ldi r16,120
.else
ldi r16,12
.endif
sts eth_ip+3,r16
;--------------------------
; set netmask
;--------------------------
ldi r16,255
sts eth_netmask+0,r16
ldi r16,255
sts eth_netmask+1,r16
ldi r16,255
sts eth_netmask+2,r16
ldi r16,0
sts eth_netmask+3,r16
rcall netSetLocalIP
rcall mainLoop
;--------------------------
; set socket type to tcp
;--------------------------
ldi r16,SOCK_STREAM
sts eth_sockettype,r16
;--------------------------
; open socket for client connections to em01
;--------------------------
ldi r16,NET_INITSOCKET_LISTEN
sts eth_initSocketNumber,r16
rcall netOpenSocket
rcall mainLoop
;--------------------------
; setup second socket to listen on port 23
;--------------------------
rcall netUseSocketListen
ldi r16,low(23)
sts eth_portListen+0,r16
ldi r16,high(23)
sts eth_portListen+1,r16
rcall netBind
rcall mainLoop
rcall netUseSocketListen
ldi r16,low(23)
sts eth_portListen+0,r16
ldi r16,high(23)
sts eth_portListen+1,r16
rcall netListen
rcall mainLoop
ret
;----------------------------------
; handle responds from em01
;----------------------------------
handleEM01Response:
lds r16,eth_datareceivebuffer+3
cpi r16,NET_CMDID_SETLOCALIP
breq _handleEM01ResponseSetLocalIP
cpi r16,NET_CMDID_OPENSOCKET
breq _handleEM01ResponseOpenSocket
; cpi r16,NET_CMDID_BIND
; cpi r16,NET_CMDID_LISTEN
; cpi r16,NET_CMDID_SENDDATATCP
cpi r16,NET_ACTIONID_ONACCEPT
breq _handleEM01ResponseOnAccept
cpi r16,NET_ACTIONID_ONRECEIVEDATA_TCP
breq _handleEM01ResponseOnReceiveDataTCP
cpi r16,NET_ACTIONID_ONREMOTECLOSE
breq _handleEM01ResponseOnRemoteClose
ret
_handleEM01ResponseOnAccept:
rcall processAcceptData
ret
_handleEM01ResponseOnReceiveDataTCP:
rcall processReceiveData
ret
_handleEM01ResponseOnRemoteClose:
rcall processRemoteClose
ret
_handleEM01ResponseSetLocalIP:
lds r16,eth_datareceivebuffer+3+2
cpi r16,NET_CMDSUBID_SETLOCALIP
breq _handleEM01ResponseSetLocalIPSub
ret
_handleEM01ResponseSetLocalIPSub:
ret
_handleEM01ResponseOpenSocket:
lds r16,eth_initSocketNumber
cpi r16,NET_INITSOCKET_CONNECT
brne _initsocketdata2
lds r16,eth_datareceivebuffer+7
sts eth_socketConnect+0,r16
lds r16,eth_datareceivebuffer+8
sts eth_socketConnect+1,r16
lds r16,eth_datareceivebuffer+9
sts eth_socketConnect+2,r16
lds r16,eth_datareceivebuffer+10
sts eth_socketConnect+3,r16
ldi r16,5
sts init,r16
ret
_initsocketdata2:
cpi r16,NET_INITSOCKET_LISTEN
brne _initsocketdata3
lds r16,eth_datareceivebuffer+7
sts eth_socketListen+0,r16
lds r16,eth_datareceivebuffer+8
sts eth_socketListen+1,r16
lds r16,eth_datareceivebuffer+9
sts eth_socketListen+2,r16
lds r16,eth_datareceivebuffer+10
sts eth_socketListen+3,r16
ldi r16,7
sts init,r16
ret
_initsocketdata3:
cpi r16,NET_INITSOCKET_LISTEN
brne _initsocketdata4
ret
_initsocketdata4:
ret
;----------------------------------
; a network connection to em01 was established
; get data from client socket and send welcome text back
;----------------------------------
processAcceptData:
ldi r16,1
sts eth_clientConnected,r16
;--------------------------
; get data from new socket
;--------------------------
rcall netGetSocketAcceptData
;--------------------------
; load data to send data to client
;--------------------------
rcall netLoadSocketAcceptData
;--------------------------
; send welcome text
;--------------------------
rcall loadWelcomeTxt
rcall netSendDataTCP
rcall mainLoop
rcall loadCmdTxt
rcall netSendDataTCP
rcall mainLoop
ret
;----------------------------------
; process client requests
;----------------------------------
processReceiveData:
rcall netIsAcceptSocket
brne _processReceiveData1
rcall handleClient
; if connection is still active, then send cmd_txt
lds r16,eth_socketAccept+0
cpi r16,-1
breq _processReceiveData
rcall loadCmdTxt
rcall netUseSocketAccept
rcall netSendDataTCP
rcall mainLoop
_processReceiveData:
ret
_processReceiveData1:
rcall netIsConnectSocket
brne _processReceiveData2
; handle data from homepage
ldi zl,low(eth_datareceivebuffer)
ldi zh,high(eth_datareceivebuffer)
ret
_processReceiveData2:
ret
;----------------------------------
; close sockets
;----------------------------------
processRemoteClose:
rcall netGetSocket
rcall netCloseSocket
rcall mainLoop
rcall netIsAcceptSocket
brne _processRemoteClose1
rcall netUnsetSocketAccept
clr r16
sts eth_clientConnected,r16
ret
_processRemoteClose1:
rcall netIsConnectSocket
brne _processRemoteClose2
rcall netUnsetSocketConnect
ret
_processRemoteClose2:
ret
;----------------------------------
; handle user input
;----------------------------------
handleClient:
;--------------------------
; get first byte from data buffer
;--------------------------
lds r16,eth_datareceivebuffer+18
cpi r16,'.'
brne _handleClient1
rcall netLoadSocketAcceptData
;--------------------------
; send bye text
;--------------------------
rcall loadByeTxt
rcall netSendDataTCP
rcall mainLoop
;--------------------------
; close connection
;--------------------------
rcall netCloseSocket
rcall mainLoop
rcall netUnsetSocketAccept
clr r16
sts eth_clientConnected,r16
ret
_handleClient1:
cpi r16,'h'
brne _handleClient2
rcall netUseSocketAccept
;--------------------------
; send help text
;--------------------------
rcall loadHelpTxt
rcall netSendDataTCP
rcall mainLoop
ret
_handleClient2:
ret
;----------------------------------
; load text to data buffer
;----------------------------------
loadHTTPRequest:
ldi zl,low(http_request*2)
ldi zh,high(http_request*2)
rjmp _loadData
loadWelcomeTxt:
ldi zl,low(welcome_txt*2)
ldi zh,high(welcome_txt*2)
rjmp _loadData
loadByeTxt:
ldi zl,low(bye_txt*2)
ldi zh,high(bye_txt*2)
rjmp _loadData
loadCmdTxt:
ldi zl,low(cmd_txt*2)
ldi zh,high(cmd_txt*2)
rjmp _loadData
loadConnectionInUseTxt:
ldi zl,low(coninuse_txt*2)
ldi zh,high(coninuse_txt*2)
rjmp _loadData
loadHelpTxt:
ldi zl,low(help_txt*2)
ldi zh,high(help_txt*2)
rjmp _loadData
;--------------------------
_loadData:
ldi yl,low(eth_databuffer)
ldi yh,high(eth_databuffer)
clr r17
_copyloop:
lpm r16,Z+
cpi r16,0
breq _copy
st Y+,r16
inc r17
rjmp _copyloop
_copy:
sts eth_datalen,r17
ret
;----------------------------------
; webserer ip is 10.0.0.1, port is 80
;----------------------------------
loadWebServerIP:
ldi r16,10
sts eth_targetIP+0,r16
ldi r16,0
sts eth_targetIP+1,r16
ldi r16,0
sts eth_targetIP+2,r16
ldi r16,1
sts eth_targetIP+3,r16
ldi r16,low(80)
sts eth_portConnect+0,r16
ldi r16,high(80)
sts eth_portConnect+1,r16
ret
;--------------------------
; download homepage
;--------------------------
webDownload:
clr r16
sts homepage64Block,r16
;--------------------------
; open socket for connections
;--------------------------
ldi r16,NET_INITSOCKET_CONNECT
sts eth_initSocketNumber,r16
rcall netOpenSocket
rcall mainLoop
;--------------------------
; load socket values for connection to a server
;--------------------------
rcall netUseSocketConnect
;--------------------------
; load ip and port of web server
;--------------------------
rcall loadWebServerIP
;--------------------------
; connect to the server
;--------------------------
rcall netConnect
rcall mainLoop
;--------------------------
; load http string
;--------------------------
rcall loadHTTPRequest
;--------------------------
; send the request to the web server
;--------------------------
rcall netSendDataTCP
rcall mainLoop
ret
;----------------------------------
; include em01 functions
;----------------------------------
.include "em01/em01.asm"
;----------------------------------
; include usart functions
;----------------------------------
.include "usart/usart.asm"
;----------------------------------
; text
;----------------------------------
http_request: .db "GET / HTTP/1.0",0xa,0xa,0x0,0x0
welcome_txt: .db "------------------------------------",0x0d,0x0a
.db "Welcome to the PLoP network device! ",0x0d,0x0a
.db "Press '.' to quit and 'h' for help",0x0d,0xa,0x0a,0
help_txt: .db "Help text:",0x0d,0x0a
.db ". quit ",0x0d,0x0a
.db "h this text",0x0d,0x0a,0x0a,0
bye_txt: .db "Bye",0xd,0xa,0
cmd_txt: .db "cmd> ",0
coninuse_txt: .db "Connection in use",0xd,0xa,0
;================================================================
; data
;================================================================
.dseg
;----------------------------------
; include em01 variables
;----------------------------------
.include "em01/em01data.asm"
homepage64Block: .byte 1
init: .byte 1
File: em01/em01.asm
;**********************************************************************
;
; Copyright (C) 2007-2008 Elmar Hanlhofer http://www.plop.at
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
;
;
;**********************************************************************
;============================================
; function list
;============================================
;
; em01InitCommand
;
; netSendPacket
; netSetLocalIP
; netOpenSocket
; netBind
; netConnect
; netListen
; netSendDataTCP
; netCloseSocket
;
; netUseSocketListen
; netUseSocketConnect
; netUseSocketAccept
; netGetSocketAcceptData
; netLoadSocketAcceptData
; netIsConnectSocket
; netIsListenSocket
;
; em01CRC
; em01SendBuffer
; em01ReceiveBuffer
; em01Wait
;
; netUnsetSocketConnect
; netUnsetSocketListen
; netUnsetSocketAccept
;-----------------------------
; setup buffer pointer and write first packet byte
;-----------------------------
em01InitCommand:
ldi zl,low(eth_datasendbuffer)
ldi zh,high(eth_datasendbuffer)
ldi r16,NET_ID_DATAPACKET
st Z+,r16
ret
;-----------------------------
; write last packet byte
; calculate crc
; send the buffer to em01
;-----------------------------
netSendPacket:
; end byte
ldi r16,NET_ENDBYTE
st Z+,r16
rcall em01CRC
rcall em01SendBuffer
ret
;-----------------------------
; setup em01 ip address
;-----------------------------
netSetLocalIP:
;----------------------
; init packet
;----------------------
rcall em01InitCommand
;----------------------
; data length
;----------------------
ldi r16,NET_CMDLEN_SETLOCALIP
st Z+,r16
;----------------------
; command start byte
;----------------------
ldi r16,NET_CMDSTARTBYTE
st Z+,r16
;----------------------
; id of command
;----------------------
ldi r16,NET_CMDID_SETLOCALIP
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; sub id of command
;----------------------
ldi r16,NET_CMDSUBID_SETLOCALIP
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; fill data with ip address
;----------------------
lds r16,eth_ip+0
st Z+,r16
lds r16,eth_ip+1
st Z+,r16
lds r16,eth_ip+2
st Z+,r16
lds r16,eth_ip+3
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; fill data with netmask
;----------------------
lds r16,eth_netmask+0
st Z+,r16
lds r16,eth_netmask+1
st Z+,r16
lds r16,eth_netmask+2
st Z+,r16
lds r16,eth_netmask+3
st Z+,r16
;----------------------
; close packet and send to em01
;----------------------
rcall netSendPacket
ret
;-----------------------------
; open a new socket
;-----------------------------
netOpenSocket:
;----------------------
; init packet
;----------------------
rcall em01InitCommand
;----------------------
; data length
;----------------------
ldi r16,NET_CMDLEN_OPENSOCKET
st Z+,r16
;----------------------
; command start byte
;----------------------
ldi r16,NET_CMDSTARTBYTE
st Z+,r16
;----------------------
; id of command
;----------------------
ldi r16,NET_CMDID_OPENSOCKET
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; address format
;----------------------
ldi r16,AF_INET
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; socket type
;----------------------
lds r16,eth_sockettype
st Z+,r16
;----------------------
; close packet and send to em01
;----------------------
rcall netSendPacket
;----------------------
; return error value
;----------------------
lds r16,eth_datareceivebuffer+5
sts eth_error,r16
ret
;-----------------------------
; accept data from clients on a port
;-----------------------------
netBind:
;----------------------
; init packet
;----------------------
rcall em01InitCommand
;----------------------
; data length
;----------------------
ldi r16,NET_CMDLEN_BIND
st Z+,r16
;----------------------
; command start byte
;----------------------
ldi r16,NET_CMDSTARTBYTE
st Z+,r16
;----------------------
; id of command
;----------------------
ldi r16,NET_CMDID_BIND
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; socket
;----------------------
lds r16,eth_socket+0
st Z+,r16
lds r16,eth_socket+1
st Z+,r16
lds r16,eth_socket+2
st Z+,r16
lds r16,eth_socket+3
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; sa block size
;----------------------
clr r16
st Z+,r16
ldi r16,16
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; sa block
;----------------------
ldi r16,0x10
st Z+,r16
;----------------------
; address format
;----------------------
ldi r16,AF_INET
st Z+,r16
;----------------------
;port
;----------------------
lds r16,eth_portListen+1
st Z+,r16
lds r16,eth_portListen+0
st Z+,r16
;----------------------
; target ip
;----------------------
clr r16 ; accept fom any ip
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r16
;----------------------
; reserved
;----------------------
clr r16
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r16
;----------------------
; close packet and send to em01
;----------------------
rcall netSendPacket
;----------------------
; return error value
;----------------------
lds r16,eth_datareceivebuffer+5
sts eth_error,r16
ret
;-----------------------------
; connect to a server with tcp
;-----------------------------
netConnect:
;----------------------
; init packet
;----------------------
rcall em01InitCommand
;----------------------
; data length
;----------------------
ldi r16,NET_CMDLEN_CONNECT
st Z+,r16
;----------------------
; command start byte
;----------------------
ldi r16,NET_CMDSTARTBYTE
st Z+,r16
;----------------------
; id of command
;----------------------
ldi r16,NET_CMDID_CONNECT
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; socket
;----------------------
lds r16,eth_socket+0
st Z+,r16
lds r16,eth_socket+1
st Z+,r16
lds r16,eth_socket+2
st Z+,r16
lds r16,eth_socket+3
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; timeout
;----------------------
ldi r16,50
st Z+,r16
clr r16
st Z+,r16
st Z+,r16
ldi r16,50
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; sa block size
;----------------------
clr r16
st Z+,r16
ldi r16,16
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; sa block
;----------------------
ldi r16,0x10
st Z+,r16
;----------------------
; address format
;----------------------
ldi r16,AF_INET
st Z+,r16
;----------------------
;port
;----------------------
lds r16,eth_portConnect+1
st Z+,r16
lds r16,eth_portConnect+0
st Z+,r16
;----------------------
; target ip
;----------------------
lds r16,eth_targetIP+0
st Z+,r16
lds r16,eth_targetIP+1
st Z+,r16
lds r16,eth_targetIP+2
st Z+,r16
lds r16,eth_targetIP+3
st Z+,r16
;----------------------
; reserved
;----------------------
clr r16
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r16
;----------------------
; close packet and send to em01
;----------------------
rcall netSendPacket
;----------------------
; return error value
;----------------------
lds r16,eth_datareceivebuffer+5
sts eth_error,r16
ret
;-----------------------------
; accept only one client
;-----------------------------
netListen:
;----------------------
; init packet
;----------------------
rcall em01InitCommand
;----------------------
; data length
;----------------------
ldi r16,NET_CMDLEN_LISTEN
st Z+,r16
;----------------------
; command start byte
;----------------------
ldi r16,NET_CMDSTARTBYTE
st Z+,r16
;----------------------
; id of command
;----------------------
ldi r16,NET_CMDID_LISTEN
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; socket
;----------------------
lds r16,eth_socket+0
st Z+,r16
lds r16,eth_socket+1
st Z+,r16
lds r16,eth_socket+2
st Z+,r16
lds r16,eth_socket+3
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; back logs
;----------------------
clr r16
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r16
;----------------------
; close packet and send to em01
;----------------------
rcall netSendPacket
;----------------------
; return error value
;----------------------
lds r16,eth_datareceivebuffer+5
sts eth_error,r16
ret
;-----------------------------
; send data to a server with tcp
;-----------------------------
netSendDataTCP:
;----------------------
; init packet
;----------------------
rcall em01InitCommand
;----------------------
; data length
;----------------------
ldi r16,17
lds r17,eth_datalen
add r16,r17
st Z+,r16
;----------------------
; command start byte
;----------------------
ldi r16,NET_CMDSTARTBYTE
st Z+,r16
;----------------------
; id of command
;----------------------
ldi r16,NET_CMDID_SENDDATATCP
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; socket
;----------------------
lds r16,eth_socket+0
st Z+,r16
lds r16,eth_socket+1
st Z+,r16
lds r16,eth_socket+2
st Z+,r16
lds r16,eth_socket+3
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; flags
;----------------------
clr r16
st Z+,r16
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; senddata len
;----------------------
clr r16
st Z+,r16
st Z+,r16
st Z+,r16
st Z+,r17
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; data
;----------------------
ldi yl,low(eth_databuffer)
ldi yh,high(eth_databuffer)
_netSendDataTCPLoop:
ld r16,y+
st z+,r16
dec r17
brne _netSendDataTCPLoop
;----------------------
; close packet and send to em01
;----------------------
rcall netSendPacket
ret
;-----------------------------
; close a socket
;-----------------------------
netCloseSocket:
;----------------------
; init packet
;----------------------
rcall em01InitCommand
;----------------------
; data length
;----------------------
ldi r16,NET_CMDLEN_CLOSESOCKET
st Z+,r16
;----------------------
; command start byte
;----------------------
ldi r16,NET_CMDSTARTBYTE
st Z+,r16
;----------------------
; id of command
;----------------------
ldi r16,NET_CMDID_CLOSESOCKET
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; socket
;----------------------
lds r16,eth_socket+0
st Z+,r16
lds r16,eth_socket+1
st Z+,r16
lds r16,eth_socket+2
st Z+,r16
lds r16,eth_socket+3
st Z+,r16
;----------------------
; terminator byte
;----------------------
ldi r16,NET_TERMINATORBYTE
st Z+,r16
;----------------------
; close packet and send to em01
;----------------------
rcall netSendPacket
;----------------------
; return error value
;----------------------
lds r16,eth_datareceivebuffer+5
sts eth_error,r16
ret
;-----------------------------
; load data of listen socket
;-----------------------------
netUseSocketListen:
lds r16,eth_socketListen+0
sts eth_socket+0,r16
lds r16,eth_socketListen+1
sts eth_socket+1,r16
lds r16,eth_socketListen+2
sts eth_socket+2,r16
lds r16,eth_socketListen+3
sts eth_socket+3,r16
ret
;-----------------------------
; load data of connect socket
;-----------------------------
netUseSocketConnect:
lds r16,eth_socketConnect+0
sts eth_socket+0,r16
lds r16,eth_socketConnect+1
sts eth_socket+1,r16
lds r16,eth_socketConnect+2
sts eth_socket+2,r16
lds r16,eth_socketConnect+3
sts eth_socket+3,r16
ret
;-----------------------------
; load data of accept socket
;-----------------------------
netUseSocketAccept:
lds r16,eth_socketAccept+0
sts eth_socket+0,r16
lds r16,eth_socketAccept+1
sts eth_socket+1,r16
lds r16,eth_socketAccept+2
sts eth_socket+2,r16
lds r16,eth_socketAccept+3
sts eth_socket+3,r16
ret
;-----------------------------
; get socket data from client
;-----------------------------
netGetSocketAcceptData:
lds r16,eth_datareceivebuffer+5
sts eth_socketAccept+0,r16
lds r16,eth_datareceivebuffer+6
sts eth_socketAccept+1,r16
lds r16,eth_datareceivebuffer+7
sts eth_socketAccept+2,r16
lds r16,eth_datareceivebuffer+8
sts eth_socketAccept+3,r16
lds r16,eth_datareceivebuffer+13+2
sts eth_socketAcceptPort+1,r16
lds r16,eth_datareceivebuffer+13+3
sts eth_socketAcceptPort+0,r16
lds r16,eth_datareceivebuffer+13+4
sts eth_socketAcceptIP+0,r16
lds r16,eth_datareceivebuffer+13+5
sts eth_socketAcceptIP+1,r16
lds r16,eth_datareceivebuffer+13+6
sts eth_socketAcceptIP+2,r16
lds r16,eth_datareceivebuffer+13+7
sts eth_socketAcceptIP+3,r16
ret
;-----------------------------
; get socket
;-----------------------------
netGetSocket:
lds r16,eth_datareceivebuffer+5
sts eth_socket+0,r16
lds r16,eth_datareceivebuffer+6
sts eth_socket+1,r16
lds r16,eth_datareceivebuffer+7
sts eth_socket+2,r16
lds r16,eth_datareceivebuffer+8
sts eth_socket+3,r16
ret
;-----------------------------
; load client socket data
;-----------------------------
netLoadSocketAcceptData:
lds r16,eth_socketAccept+0
sts eth_socket+0,r16
lds r16,eth_socketAccept+1
sts eth_socket+1,r16
lds r16,eth_socketAccept+2
sts eth_socket+2,r16
lds r16,eth_socketAccept+3
sts eth_socket+3,r16
lds r16,eth_socketAcceptPort+0
sts eth_portconnect+0,r16
lds r16,eth_socketAcceptPort+1
sts eth_portconnect+1,r16
lds r16,eth_socketAcceptIP+0
sts eth_targetIP+0,r16
lds r16,eth_socketAcceptIP+1
sts eth_targetIP+1,r16
lds r16,eth_socketAcceptIP+2
sts eth_targetIP+2,r16
lds r16,eth_socketAcceptIP+3
sts eth_targetIP+3,r16
ret
;-----------------------------
; check for socket from connection to server
;-----------------------------
netIsConnectSocket:
push r16
push r17
lds r16,eth_socketConnect+0
lds r17,eth_datareceivebuffer+5
cp r16,r17
brne _netIsConnectSocket
lds r16,eth_socketConnect+1
lds r17,eth_datareceivebuffer+6
cp r16,r17
brne _netIsConnectSocket
lds r16,eth_socketConnect+2
lds r17,eth_datareceivebuffer+7
cp r16,r17
brne _netIsConnectSocket
lds r16,eth_socketConnect+3
lds r17,eth_datareceivebuffer+8
cp r16,r17
_netIsConnectSocket:
pop r17
pop r16
ret
;-----------------------------
; check for socket listen
;-----------------------------
netIsListenSocket:
push r16
push r17
lds r16,eth_socketListen+0
lds r17,eth_datareceivebuffer+5
cp r16,r17
brne _netIsListenSocket
lds r16,eth_socketListen+1
lds r17,eth_datareceivebuffer+6
cp r16,r17
brne _netIsListenSocket
lds r16,eth_socketListen+2
lds r17,eth_datareceivebuffer+7
cp r16,r17
brne _netIsListenSocket
lds r16,eth_socketListen+3
lds r17,eth_datareceivebuffer+8
cp r16,r17
_netIsListenSocket:
pop r17
pop r16
ret
;-----------------------------
; check for socket connection from client
;-----------------------------
netIsAcceptSocket:
push r16
push r17
lds r16,eth_socketAccept+0
lds r17,eth_datareceivebuffer+5
cp r16,r17
brne _netIsAcceptSocket
lds r16,eth_socketAccept+1
lds r17,eth_datareceivebuffer+6
cp r16,r17
brne _netIsAcceptSocket
lds r16,eth_socketAccept+2
lds r17,eth_datareceivebuffer+7
cp r16,r17
brne _netIsAcceptSocket
lds r16,eth_socketAccept+3
lds r17,eth_datareceivebuffer+8
cp r16,r17
_netIsAcceptSocket:
pop r17
pop r16
ret
;-----------------------------
; calculate crc
;-----------------------------
em01CRC:
push r16
push r17
push r18
push r20
push r21
push xl
push xh
push yl
push yh
push zl
push zh
;----------------------
; yh:yl = crc sum
;----------------------
clr yl
clr yh
;----------------------
; xh:xl = mult
;----------------------
ldi xl,133
clr xh
ldi zl,low(eth_datasendbuffer+1)
ldi zh,high(eth_datasendbuffer+1)
;----------------------
; get data length
;----------------------
ld r18,z+
_crcLoop:
ld r16,z+
clr r17
clr r20
clr r21
push xl
push xh
_crcMult:
add r20,r16
adc r21,r17
sbiw xl,1
brne _crcMult
pop xh
pop xl
add yl,r20
adc yh,r21
;---------------------
cpi xh,high(0xffff-6)
brlo _crcMultcor
breq _crcMultcor
;---------------------
_crcMultcor1:
clr r20
clr r21
sub r20,xl
sbc r21,xh
ldi xl,6
clr xh
sub xl,r20
sbc xh,r21
rjmp _crcNext
;---------------------
_crcMultcor:
cpi xl,low(0xffff-6)
brlo _crcMultcor2
breq _crcMultcor2
rjmp _crcMultcor1
;---------------------
_crcMultcor2:
clr r17
ldi r16,6
add xl,r16
adc xh,r17
;---------------------
_crcNext:
dec r18
brne _crcLoop
ldi r16,0x5b
eor yl,r16
ldi r16,0xac
eor yh,r16
;----------------------
; write crc word
;----------------------
st z+,yl
st z+,yh
pop zh
pop zl
pop yh
pop yl
pop xh
pop xl
pop r21
pop r20
pop r18
pop r17
pop r16
ret
;-----------------------------
; send the packet to em01
;-----------------------------
em01SendBuffer:
push r16
push r17
push r18
push zl
push zh
;----------------------
; wait for em01 to accept data
;----------------------
rcall em01Wait
;----------------------
; send buffer
;----------------------
ldi zl,low(eth_datasendbuffer)
ldi zh,high(eth_datasendbuffer)
lds r18,eth_datasendbuffer+1
ldi r17,4
add r18,r17
_netSendBuffer:
ld r16,z+
rcall serialSend
dec r18
brne _netSendBuffer
pop zh
pop zl
pop r18
pop r17
pop r16
ret
;-----------------------------
; read data from em01
;-----------------------------
em01ReceiveBuffer:
push r16
push r18
push zl
push zh
ldi zl,low(eth_datareceivebuffer)
ldi zh,high(eth_datareceivebuffer)
rcall serialRead
brcs _netReceiveBufferexit
st z+,r16
rcall serialRead
brcs _netReceiveBufferexit
st z+,r16
mov r18,r16
rcall serialRead
st z+,r16
rcall serialRead
st z+,r16
cpi r16,0x50
brne _netReceiveBuffer
ldi r18,12+1
_netReceiveBuffer:
_netReceiveBufferLoop:
rcall serialRead
brcs _netReceiveBufferexit
st z+,r16
dec r18
brne _netReceiveBufferLoop
_netReceiveBufferexit:
pop zh
pop zl
pop r18
pop r16
ret
;-----------------------------
; wait for em01 until it accept data
;-----------------------------
em01Wait:
sbic EM01_PIN,EM01_RTS
rjmp em01Wait
ret
netUnsetSocketConnect:
ser r16
sts eth_socketConnect+0,r16
sts eth_socketConnect+1,r16
sts eth_socketConnect+2,r16
sts eth_socketConnect+3,r16
ret
netUnsetSocketListen:
ser r16
sts eth_socketListen+0,r16
sts eth_socketListen+1,r16
sts eth_socketListen+2,r16
sts eth_socketListen+3,r16
ret
netUnsetSocketAccept:
ser r16
sts eth_socketAccept+0,r16
sts eth_socketAccept+1,r16
sts eth_socketAccept+2,r16
sts eth_socketAccept+3,r16
ret
File: em01/em01const.asm ;********************************************************************** ; ; Copyright (C) 2007-2008 Elmar Hanlhofer http://www.plop.at ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; ; ;********************************************************************** .equ AF_INET = 2 ; address format .equ SOCK_STREAM = 1 ; address type TCP .equ SOCK_DGRAM = 2 ; address type UDP ;-------------------------------------------- ;.equ EM01_PORT = PORTC ;.equ EM01_PIN = PINC ;.equ EM01_DDR = DDRC ;.equ EM01_BAUD0 = PC0 ;.equ EM01_BAUD1 = PC1 ;.equ EM01_BAUD2 = PC2 ;.equ EM01_CTS = PC3 ;.equ EM01_RTS = PC4 ;.equ EM01_RESET = PC5 ;-------------------------------------------- .equ NET_ID_DATAPACKET = 0x50 .equ NET_CMDSTARTBYTE = 0x21 .equ NET_TERMINATORBYTE = 0x2C .equ NET_ENDBYTE = 0x3B .equ NET_CMDID_SETLOCALIP = 0x01 .equ NET_CMDSUBID_SETLOCALIP = 0x04 .equ NET_CMDLEN_SETLOCALIP = 0x0f .equ NET_CMDID_OPENSOCKET = 0x03 .equ NET_CMDLEN_OPENSOCKET = 0x07 .equ NET_CMDID_BIND = 0x04 .equ NET_CMDLEN_BIND = 28 .equ NET_CMDID_CONNECT = 0x05 .equ NET_CMDLEN_CONNECT = 33 .equ NET_CMDID_LISTEN = 0x06 .equ NET_CMDLEN_LISTEN = 13 .equ NET_CMDID_CLOSESOCKET = 0x07 .equ NET_CMDLEN_CLOSESOCKET = 0x09 .equ NET_CMDID_SENDDATATCP = 0x08 ;-------------------------------------------- .equ NET_ACTIONID_ONACCEPT = 64 .equ NET_ACTIONID_ONRECEIVEDATA_TCP = 65 .equ NET_ACTIONID_ONREMOTECLOSE = 66 ;-------------------------------------------- .equ NET_INITSOCKET_CONNECT = 1 .equ NET_INITSOCKET_LISTEN = 2 .equ NET_INITSOCKET_ACCEPT = 3 File: em01/em01data.asm ;********************************************************************** ; ; Copyright (C) 2007-2008 Elmar Hanlhofer http://www.plop.at ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; ; ;********************************************************************** eth_ip: .byte 4 eth_netmask: .byte 4 eth_sockettype: .byte 1 eth_socket: .byte 4 eth_socketListen: .byte 4 eth_socketConnect: .byte 4 eth_socketAccept: .byte 4 eth_portListen: .byte 2 eth_portConnect: .byte 2 eth_targetIP: .byte 4 eth_error: .byte 1 eth_datasendbuffer: .byte 5+149 eth_datareceivebuffer: .byte 5+149 eth_datalen: .byte 1 eth_databuffer: .byte 60 eth_socketAcceptIP: .byte 4 eth_socketAcceptPort: .byte 2 eth_initSocketNumber: .byte 1 eth_clientConnected: .byte 1 File: usart/usart.asm
;**********************************************************************
;
; Copyright (C) 2007-2008 Elmar Hanlhofer http://www.plop.at
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
;
;
;**********************************************************************
; send data to usart
serialSend:
sbis UCSRA,UDRE
rjmp serialSend
out UDR,r16
ret
; read data from usart
serialRead:
push r16
push r17
clr r16
ldi r17,0
_serialRead:
sbis UCSRA,RXC
rjmp _serialRead
pop r17
pop r16
in r16,UDR
clc
ret
© by Elmar Hanlhofer |
|||||||||||||||||