/* * Copyright (c) Martin Schoeberl, martin@jopdesign.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Martin Schoeberl * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ package oebb; /* * Changelog: * 2002-10-24 creation. * 2004-12-04 A 'special' version for the OEBB project. * * * TODO: use a source port as TID. * timeout and resend or cancel connection. * */ import com.jopdesign.sys.Native; import util.Amd; import util.Timer; import ejip.*; /** * BgTftp.java: A simple TFTP Server. see rfc1350. */ public class BgTftp extends Tftp { final static int MAX_BLOCKS = 128; protected int[] sector; BgTftp(Ejip ejipRef) { super(ejipRef); // +1 is for the final block on a 64KB write // that contains no data sector = new int[(MAX_BLOCKS+1)*512/4]; } /** * Save data for future programming. */ protected void write(int[] buf, int block) { int i, j; int base; block--; // data blocks start with 1 i = fn>>8; Timer.wd(); // toggle for each block? System.out.print("Save "); System.out.println(block); if (i=='f') { // program flash // here we count in 128 word blocks = 512 byte blocks base = (block<<7); if (block>MAX_BLOCKS) { System.out.println("Too many blocks!"); return; } // base += ((fn&0xff)-'0')<<16; // 64 KB sector for (j=0; j<128; ++j) { sector[base+j] = buf[Udp.DATA+1+j]; } } } /** * Program one sector of the Flash. */ protected void eof(int cnt) { System.out.print("Program "); System.out.print(cnt); System.out.println(" blocks"); int i, j, w; int base; i = fn>>8; if (i!='f') return; // filename not valid base = ((fn&0xff)-'0')<<16; // 64 KB sector // System.out.print("Erase sector "); System.out.println(base); synchronized (sector) { Amd.erase(base); System.out.println("Program "); for (i=0; i<cnt && i<MAX_BLOCKS; ++i) { Timer.wd(); // toggle for each block? System.out.print(" blk "); System.out.print(i); for (j=0; j<128; ++j) { w = sector[i*128+j]; Amd.program(base, w>>>24); Amd.program(base+1, w>>>16); Amd.program(base+2, w>>>8); Amd.program(base+3, w); base += 4; } } } } /** * move log data * @author admin * */ void moveLog() { int i, j; // synchronized (sector) { Timer.wd(); j = sector.length; for (i=0; i<j; ++i) { sector[i] = -1; } for (i=0; i<Flash.CONFIG_LEN/4; ++i) { sector[i] = intVal(Flash.BGID_START+(i<<2)); } j = Flash.CONFIG_LEN/4; for (i=8000; i<16384; ++i) { sector[j] = intVal(Flash.BGID_START+(i<<2)); ++j; } fn = (((int)'f')<<8) + '3'; eof(MAX_BLOCKS); // } } /** * Set bgid if it got lost * @param bgid */ void programBgid(int bgid) { int i,j; Timer.wd(); j = sector.length; for (i=0; i<j; ++i) { sector[i] = -1; } sector[0] = bgid; fn = (((int)'f')<<8) + '3'; eof(1); } int intVal(int addr) { int val = 0; synchronized (sector) { for (int i=0; i<4; ++i) { val <<= 8; val += Native.rdMem(addr+i); } } return val; } }