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