English / Deutsch

The blue Plop Clock (year 2006)


Introduction


This 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


Photo

Plop Clock v0.1
Format: AVI 3,8 MB


Wilke EM-01 Network routines


I 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:
The processor is an ATMEL ATMEGA16 with 4Mhz frequency. The EM-01 is connected with the serial port at 19200 baud. The EM-01 will be controlled with the PORTC of the ATMEGA16.

You can connect to the Atmel with telnet.
IP: 10.0.0.120
Port: 23
Telnet 10.0.0.120
The program send a welcome text. Use '.' to quit and 'h' to get a help text.

Info: No default Gateway is set. So the program will work only in your local network.

eth.asm - Mainprogram
em01/em01.asm - Network and EM-01 functions
em01/em01const.asm - EM-01 constants
em01/em01data.asm - Network variables
usart/usart.asm - Functions for the serial communication

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

    

© 2014 by Elmar Hanlhofer