burner.c Source File






Misc >
Help >
FAQ >


Links >



burner.c

00001 /* burner.c -- Burn the internal EEPROM
00002 Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
00003 Written by Stephane Carrez (stcarrez@nerim.fr)
00004 
00005 This file is part of GEL.
00006 
00007 GEL is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2, or (at your option)
00010 any later version.
00011 
00012 GEL is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with GEL; see the file COPYING. If not, write to
00019 the Free Software Foundation, 59 Temple Place - Suite 330,
00020 Boston, MA 02111-1307, USA. */
00021 
00074 #include <sys/ports.h>
00075 
00076 typedef void __attribute__ ((noreturn)) (* func)();
00077 
00078 static unsigned short get_char (void);
00079 static unsigned char* get_addr (void);
00080 volatile int __attribute__((noreturn)) main ();
00081 static void flush (void);
00082 void eeprom_write_byte (unsigned char *p, const unsigned char value);
00083 void udelay_10ms (void);
00084 void _start (void);
00085 
00086 void
00087 _start()
00088 {
00089 __asm__ __volatile__ ("bra main");
00090 /* main (); */
00091 }
00092 
00093 static void
00094 flush ()
00095 {
00096 while (!(_io_ports[M6811_SCSR] & M6811_TDRE))
00097 continue;
00098 }
00099 
00100 static void
00101 put_char (unsigned char c)
00102 {
00103 flush ();
00104 _io_ports[M6811_SCDR] = c;
00105 _io_ports[M6811_SCCR2] |= M6811_TE;
00106 }
00107 
00108 volatile int
00109 main ()
00110 {
00111 unsigned char* addr;
00112 unsigned char c;
00113 
00114 while (1)
00115 {
00116 /* Print banner for synchronization. */
00117 put_char ('\n');
00118 put_char ('>');
00119 
00120 /* Wait for command. */
00121 c = get_char ();
00122 
00123 /* Write memory command. Command format is:
00124 
00125 M<ADDR-HIGH><ADDR-LOW><SIZE>[<DATA>]
00126 
00127 Address, size and data are passed in binary form.
00128 A size of 0 corresponds to 256 bytes.
00129 
00130 Since burning a byte can take some time, we must synchronize
00131 with the host. To do this, we echo the byte that was programmed
00132 and the host waits for it before sending the next one. If the
00133 host does not wait, we can loose some bytes. */
00134 if (c == 'M')
00135 {
00136 unsigned char size;
00137 
00138 addr = get_addr ();
00139 size = get_char ();
00140 do
00141 {
00142 *addr = get_char ();
00143 eeprom_write_byte (addr, get_char ());
00144 put_char (*addr);
00145 }
00146 while (--size != 0);
00147 }
00148 
00149 /* Go command. Command format is:
00150 
00151 G<ADDR-HIGH><ADDR-LOW>
00152 
00153 We reply with a G. Depending on the program, the final \n
00154 may not be received since we don't wait for it to be sent. */
00155 else if (c == 'G')
00156 {
00157 func handler;
00158 
00159 addr = get_addr ();
00160 put_char ('G');
00161 put_char ('\n');
00162 flush ();
00163 
00164 handler = (func) addr;
00165 handler ();
00166 }
00167 
00168 /* For others, emit something to tell we are alive. */
00169 else
00170 {
00171 put_char ('?');
00172 }
00173 }
00174 }
00175 
00176 void
00177 udelay_10ms ()
00178 {
00179 unsigned short tmp = 40000;
00180 
00181 __asm__ __volatile__ ("1: subd #1\n"
00182 " bne 1b" : "=d"(tmp) : "d"(tmp));
00183 }
00184 
00194 void 
00195 eeprom_write_byte (unsigned char *p, const unsigned char value)
00196 {
00197 unsigned char diff;
00198 
00199 diff = *p ^ value;
00200 if (diff)
00201 {
00202 if (diff & value)
00203 {
00204 /* Clear eeprom byte. */
00205 diff = *p ^ value;
00206 if (diff == 0)
00207 return;
00208 
00209 _io_ports[M6811_PPROG] = M6811_EELAT | M6811_ERASE | M6811_BYTE;
00210 *p = value;
00211 _io_ports[M6811_PPROG] = M6811_EELAT | M6811_ERASE
00212 | M6811_BYTE | M6811_EEPGM;
00213 
00214 /* Wait 10 ms. */
00215 udelay_10ms ();
00216 _io_ports[M6811_PPROG] = M6811_EELAT | M6811_ERASE | M6811_BYTE;
00217 }
00218 
00219 /* Write eeprom byte. */
00220 _io_ports[M6811_PPROG] = M6811_EELAT;
00221 *p = value;
00222 _io_ports[M6811_PPROG] = M6811_EELAT | M6811_EEPGM;
00223 
00224 /* Wait 10 ms. */
00225 udelay_10ms ();
00226 _io_ports[M6811_PPROG] = M6811_EELAT;
00227 _io_ports[M6811_PPROG] = 0;
00228 }
00229 }
00230 
00231 static unsigned char*
00232 get_addr ()
00233 {
00234 unsigned short c1, c2;
00235 
00236 c1 = get_char ();
00237 c2 = get_char ();
00238 return (unsigned char*) (((unsigned short) c1 << 8) | ((unsigned short) c2));
00239 }
00240 
00241 static unsigned short
00242 get_char ()
00243 {
00244 unsigned char c;
00245 volatile unsigned char* ports = &_io_ports[0];
00246 
00247 while (1)
00248 {
00249 c = ports[M6811_SCSR];
00250 
00251 if (c & M6811_RDRF)
00252 break;
00253 }
00254 return ports[M6811_SCDR];
00255 }

Copyright (C) 1999, 2000, 2001, 2002, 2003 Stéphane Carrez, France
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.


AltStyle によって変換されたページ (->オリジナル) /