;**********************************************************************
;
;  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





