| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 | 
							- #include <stdlib.h>
 
- #include <string.h>
 
- #include <stdio.h>
 
- #include <stdarg.h>
 
- #include <serial.h>
 
- #include <uucode.h>
 
- #include <lpc.h>
 
- const struct lpc_part lpc_parts[] = {
 
-   {"LPC1111/101", 0x041e502b, 2, 8},
 
-   {"LPC1111/101 or 102", 0x2516d02b, 2, 8},
 
-   {"LPC1111/201", 0x0416502b, 4, 8},
 
-   {"LPC1111/201 or 202", 0x2516902b, 4, 8},
 
-   
 
-   {"LPC1112/101", 0x042d502b, 2, 16},
 
-   {"LPC1112/101 or 102", 0x2524d02b, 2, 16},
 
-   {"LPC1112/201", 0x0425502b, 4, 16},
 
-   {"LPC1112/201 or 202", 0x2524902b, 4, 16},
 
-   
 
-   {"LPC1113/201", 0x0434502b, 4, 24},
 
-   {"LPC1113/201 or 202", 0x2532902b, 4, 24},
 
-   {"LPC1113/301", 0x0434102b, 8, 24},
 
-   {"LPC1113/301 or 302", 0x2532102b, 8, 24},
 
-   
 
-   {"LPC1114/201", 0x0444502b, 4, 32},
 
-   {"LPC1114/201 or 202", 0x2540902b, 4, 32},
 
-   {"LPC1114/301", 0x0444102b, 8, 32},
 
-   {"LPC1114/301 or 302", 0x2540102b, 8, 32},
 
-   
 
-   {"LPC11C12/301", 0x1421102b, 8, 16},
 
-   {"LPC11C14/301", 0x1440102b, 8, 32},
 
-   {"LPC11C22/301", 0x1431102b, 8, 16},
 
-   {"LPC11C24/301", 0x1430102b, 8, 32},
 
-   {NULL, 0, 0, 0}
 
- };
 
- const struct sprog_family lpc_family = {
 
-   .setup = (void*(*)(struct serial_device*)) lpc_setup,
 
-   .init = (void(*)(void*)) lpc_init,
 
-   .exec = (void(*)(void*, const struct sprog_data*)) lpc_exec,
 
-   .write = (void(*)(void*, const struct sprog_data*)) lpc_write,
 
-   .close = (void(*)(void*)) lpc_close
 
- };
 
-   
 
-   
 
- void lpc_ispmode(struct lpc_device *dev, int state);
 
- void lpc_reset(struct lpc_device *dev, int isp);
 
- int lpc_scanf(struct lpc_device *dev, const char *text, ...);
 
- void lpc_vprintf(struct lpc_device *dev, const char *text, va_list l);
 
- void lpc_printf(struct lpc_device *dev, const char *text, ...);
 
- int lpc_getline(struct lpc_device *dev, char *buf);
 
- int lpc_command(struct lpc_device *dev, const char *text, ...);
 
- int lpc_await_reply(struct lpc_device *dev, ...);
 
- int lpc_read_partid(struct lpc_device *dev);
 
- void lpc_write_ram(struct lpc_device *dev, const struct sprog_data *d, unsigned int addr);
 
- struct lpc_device *lpc_setup(struct serial_device *port) {
 
-   struct lpc_device *dev;
 
-   dev = malloc(sizeof(struct lpc_device));
 
-   dev->port = port;
 
-   dev->part = NULL;
 
-   lpc_reset(dev, 1);
 
-   return dev;
 
- }
 
- void lpc_init(struct lpc_device *dev) {
 
-   char buf[4096];
 
-   
 
-   serial_write(dev->port, "?");
 
-   
 
-   if(lpc_await_reply(dev, "Synchronized", NULL)==1) {
 
-       sprog_info("Synchronization successful\n");
 
-     lpc_printf(dev, "Synchronized\r\n");
 
-     if(lpc_await_reply(dev, "OK", NULL)!=1)
 
-       sprog_error("Expected OK, received '%s'\n", buf);
 
-     lpc_printf(dev, "12000\r\n");
 
-     if(lpc_await_reply(dev, "OK", NULL)!=1)
 
-       sprog_error("Expected OK, received '%s'\n", buf);
 
-   } else {
 
-     serial_write(dev->port, "\r\n");
 
-     if(lpc_await_reply(dev, "?", NULL)==1)
 
-       sprog_info("The device appears to be already synchronized\n");
 
-     else
 
-       sprog_error("Invalid device response\n");
 
-     lpc_getline(dev, buf); /* receive invalid command reply */
 
-   }
 
-   if(lpc_read_partid(dev)==0)
 
-     sprog_info("Found device: %s, %dkB Flash, %dkB RAM\n", dev->part->name, dev->part->flash, dev->part->ram);
 
- }
 
- void lpc_write(struct lpc_device *dev, const struct sprog_data *d) {
 
-   static const int chunk_sizes[] = {256, 512, 1024, 4096, 0};
 
-   struct sprog_data chunk;
 
-   int i;
 
-   int offset;
 
-   int chunk_size;
 
-   int data_size;
 
-   offset = 0;
 
-   
 
-   chunk.data = NULL;
 
-   
 
-   i = dev->part->flash/4; /* number of sectors = Flash size / 4kB */
 
-   lpc_command(dev, "P 0 %d\r\n", i);
 
-   
 
-   sprog_info("Erasing Flash memory... ");
 
-   if(lpc_command(dev, "E 0 %d\r\n", i))
 
-     sprog_info("Error\n");
 
-   else
 
-     sprog_info("OK\n");
 
-   
 
-   i = d->size/4096;
 
-   lpc_command(dev, "P 0 %d\r\n", i); /* prepare sectors for write */
 
-   
 
-   while(d->size-offset>0) {
 
-     chunk_size = d->size - offset;
 
-     for(i=0; chunk_sizes[i]; i++) {
 
-       if(chunk_sizes[i]>=chunk_size)
 
- 	break;
 
-       if(chunk_sizes[i]+1024 > dev->part->ram) {
 
- 	i--;
 
- 	break;
 
-       }
 
-     }
 
-     
 
-     chunk_size = chunk_sizes[i];
 
-     if(chunk_size==0) chunk_size = chunk_sizes[i-1];
 
-     sprog_alloc_data(&chunk, chunk_size);
 
-     
 
-     data_size = chunk_size;
 
-     if(data_size > d->size-offset)
 
-       data_size = d->size - offset;
 
-     
 
-     for(i=0; i<data_size; i++)
 
-       chunk.data[i] = d->data[offset+i];
 
-     
 
-     for(i=data_size; i<chunk_size; i++)
 
-       chunk.data[i] = 0;
 
-     
 
-     chunk.size = chunk_size;
 
-     
 
-     lpc_write_ram(dev, &chunk, 0x10000400);
 
-     
 
-     sprog_info("Copying to Flash...\n");
 
-     if(lpc_command(dev, "C %d %u %d\r\n", offset, 0x10000400, chunk_size))
 
-       sprog_error("Error while copying to flash\n");
 
-     else
 
-       sprog_info("Done!\n");
 
-     
 
-     offset += data_size;
 
-   }
 
- }
 
- void lpc_exec(struct lpc_device *dev, const struct sprog_data *d) {
 
-   lpc_write_ram(dev, d, 0x10000400);
 
-   lpc_command(dev, "U 23130\r\n");
 
-   sprog_info("Executing code... ");
 
-   if(lpc_command(dev, "G %u T\r\n", 0x10000400))
 
-     sprog_info("Error\n");
 
-   else
 
-     sprog_info("OK\n");
 
- }
 
- void lpc_write_ram(struct lpc_device *dev, const struct sprog_data *d, unsigned int addr) {
 
-   int last_offset;
 
-   int last_i;
 
-   int offset;
 
-   int checksum;
 
-   char buf[64];
 
-   int i;
 
-   int j;
 
-   
 
-   if(d->size & 3)
 
-     sprog_error("Invalid data size - should be aligned to 4\n");
 
-   
 
-   lpc_command(dev, "W %u %u\r\n", addr, d->size);
 
-   sprog_info("Writing %d bytes\n", d->size);
 
-   
 
-   last_i = 0;
 
-   last_offset = 0;
 
-   offset = 0;
 
-   sprog_progress(offset, d->size);
 
-   checksum = 0;
 
-   
 
-   for(i=0; (j = uuencode_line(d, buf, &offset, &checksum)); i++) {
 
-     lpc_printf(dev, "%s\r\n", buf);
 
-     if(j==2 || (i % 20)==19) {
 
-       lpc_printf(dev, "%u\r\n", checksum);
 
-       checksum = 0;
 
-       
 
-       switch(lpc_await_reply(dev, "OK", "RESEND", NULL)) {
 
- 	case 1:
 
- 	  last_offset = offset;
 
- 	  last_i = i;
 
- 	  break;
 
- 	case 2:
 
- 	default:
 
- 	  offset = last_offset;
 
- 	  i = last_i;
 
-       }
 
-     }
 
-     sprog_progress(offset, d->size);
 
-   }
 
-   sprog_info("\n");
 
- }
 
- int lpc_await_reply(struct lpc_device *dev, ...) {
 
-   char buf[4096];
 
-   int i;
 
-   const char *t;
 
-   va_list l;
 
-   va_start(l, dev);
 
-   if(!lpc_getline(dev, buf))
 
-     return 0;
 
-   for(i=0; buf[i]; i++) {
 
-     if(buf[i]=='\n') {
 
-       buf[i] = 0;
 
-       if(i>0) {
 
- 	if(buf[i-1]=='\r')
 
- 	  buf[i-1] = 0;
 
-       }
 
-       break;
 
-     }
 
-   }
 
-   
 
-   for(i=0; (t = va_arg(l, const char*)); i++) {
 
-     if(strcmp(buf, t)==0)
 
-       return i+1;
 
-   }
 
-   return -1;
 
- }
 
-   
 
- int lpc_getline(struct lpc_device *dev, char *buf) {
 
-   if(sprog_waitdata(dev->port, 5000)==0)
 
-     return 0;
 
-   fgets(buf, 4096, dev->port->f);
 
-   return 1;
 
- }
 
- int lpc_scanf(struct lpc_device *dev, const char *text, ...) {
 
-   int r;
 
-   char buf[4096];
 
-   va_list l;
 
-   va_start(l, text);
 
-   if(!lpc_getline(dev, buf))
 
-     return 0;
 
-   r = vsscanf(buf, text, l);
 
-   va_end(l);
 
-   return r;
 
- }
 
- void lpc_vprintf(struct lpc_device *dev, const char *text, va_list l) {
 
-   char buf[4096];
 
-   vsprintf(buf, text, l);
 
-   serial_write(dev->port, buf);
 
-   lpc_getline(dev, buf);
 
- }
 
- void lpc_printf(struct lpc_device *dev, const char *text, ...) {
 
-   va_list l;
 
-   va_start(l, text);
 
-   lpc_vprintf(dev, text, l);
 
-   va_end(l);
 
- }
 
- int lpc_command(struct lpc_device *dev, const char *text, ...) {
 
-   int res;
 
-   va_list l;
 
-   va_start(l, text);
 
-   lpc_vprintf(dev, text, l);
 
-   va_end(l);
 
-   if(lpc_scanf(dev, "%d", &res)<1)
 
-     return -1;
 
-   return res;
 
- }
 
- int lpc_read_partid(struct lpc_device *dev) {
 
-   int i;
 
-   int res;
 
-   unsigned int partid;
 
-   res = lpc_command(dev, "J\r\n");
 
-   if(res!=0)
 
-     return res;
 
-   lpc_scanf(dev, "%u", &partid);
 
-   for(i=0; lpc_parts[i].name; i++)
 
-     if(lpc_parts[i].part_id==partid)
 
-       break;
 
-   if(lpc_parts[i].name)
 
-     dev->part = &lpc_parts[i];
 
-   else
 
-     return -1;
 
-   return 0;
 
- }
 
- void lpc_ispmode(struct lpc_device *dev, int state) {
 
-   serial_setline(dev->port, SERIAL_DTR, state);
 
- }
 
- void lpc_reset(struct lpc_device *dev, int isp) {
 
-   /* TODO: configure the control lines */
 
-   serial_setline(dev->port, SERIAL_DTR, 1);
 
-   if(isp)
 
-     lpc_ispmode(dev, 1);
 
-   sprog_sleep(50);
 
-   serial_setline(dev->port, SERIAL_DTR, 0);
 
-   if(isp) {
 
-     sprog_sleep(50);
 
-     lpc_ispmode(dev, 0);
 
-   }
 
- }
 
- void lpc_close(struct lpc_device *dev) {
 
-   serial_close(dev->port);
 
-   free(dev);
 
- }
 
 
  |