English / Deutsch  -   15/Nov/2014: plopKexec update will be released soon
11/Nov/2014: Plop Linux for Raspberry PI will be released soon
06/Nov/2014: A bugfixed hfsprescue will be released in the next few days

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