--- /dev/null
+/*
+ * lpcload.c - load firmware into ram of lpc2220 via uart0
+ *
+ * author: hackbard@hackdaworld.org
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <termios.h>
+
+#define VERBOSE (1<<0)
+#define FIRMWARE (1<<1)
+
+#define CRYSTFREQ "10000"
+
+#define BUFSIZE 64
+
+void usage(void) {
+
+ printf("possible argv:\n");
+ printf(" -d <serial device>\n");
+ printf(" -f <firmware>\n");
+ printf(" -c <crystal freq>\n");
+ printf(" -v\n");
+
+}
+
+int txrx(int fd,char *buf,int *len,unsigned char v) {
+
+ int ret,cnt;
+ int i;
+
+ /* write */
+
+ if(v&VERBOSE)
+ printf(" >> ");
+ cnt=0;
+ while(*len) {
+ ret=write(fd,buf+cnt,*len);
+ if(ret<0) {
+ perror("txrx write");
+ return ret;
+ }
+ if(v&VERBOSE)
+ for(i=0;i<ret;i++)
+ printf("%c",
+ ((buf[cnt+i]>0x19)&(buf[cnt+i]<0x7f))?
+ buf[cnt+i]:'.');
+ *len-=ret;
+ cnt+=ret;
+ }
+ if(v&VERBOSE)
+ printf(" (%d)\n",cnt);
+
+ /* cut the echo */
+ // add more checking here!
+ while(cnt)
+ cnt-=read(fd,buf,cnt);
+
+ /* read */
+
+ if(v&VERBOSE)
+ printf(" << ");
+ ret=1;
+ cnt=0;
+ while(ret>0) {
+ ret=read(fd,buf+cnt,BUFSIZE-cnt);
+ if(ret<0) {
+ perror("txrx read");
+ return ret;
+ }
+ if(ret+cnt>BUFSIZE) {
+ printf("txrx read: too small buf size (%d)!\n",BUFSIZE);
+ return -1;
+ }
+ if(v&VERBOSE)
+ for(i=0;i<ret;i++)
+ printf("%c",
+ ((buf[cnt+i]>0x19)&(buf[cnt+i]<0x7f))?
+ buf[cnt+i]:'.');
+ cnt+=ret;
+ }
+ if(v&VERBOSE)
+ printf(" (%d)\n",cnt);
+ *len=cnt;
+
+ return cnt;
+}
+
+int main(int argc,char **argv) {
+
+ int i;
+ char tts[128];
+ int tts_fd;
+ char fw[128];
+ int fw_fd;
+ unsigned char info;
+ struct termios term;
+ char cfreq[8];
+ int len;
+ char buf[BUFSIZE];
+
+ /*
+ * initial ...
+ */
+
+ info=0;
+ memset(&term,0,sizeof(struct termios));
+ strncpy(cfreq,CRYSTFREQ,7);
+
+ /* parse argv */
+
+ for(i=1;i<argc;i++) {
+
+ if(argv[i][0]!='-') {
+ usage();
+ return -1;
+ }
+
+ switch(argv[i][1]) {
+ case 'd':
+ strncpy(tts,argv[++i],127);
+ break;
+ case 'f':
+ strncpy(fw,argv[++i],127);
+ info|=FIRMWARE;
+ break;
+ case 'v':
+ info|=VERBOSE;
+ break;
+ case 'c':
+ strncpy(cfreq,argv[++i],7);
+ break;
+ default:
+ usage();
+ return -1;
+ }
+
+ }
+
+ /*
+ * open serial device
+ */
+
+ tts_fd=open(tts,O_RDWR);
+ if(tts_fd<0) {
+ perror("tts open");
+ return tts_fd;
+ }
+
+ /*
+ * configure serial device
+ */
+
+ tcgetattr(tts_fd,&term);
+
+ // input/output baudrate
+
+ cfsetispeed(&term,B9600);
+ cfsetospeed(&term,B9600);
+
+ // control options -> 8n1
+
+ term.c_cflag&=~PARENB; // no parity
+ term.c_cflag&=~CSTOPB; // only 1 stop bit
+ term.c_cflag&=~CSIZE; // no bit mask for data bits
+ term.c_cflag|=CS8; // 8 data bits
+
+ // line options -> raw input
+
+ term.c_lflag&=~(ICANON|ECHO|ECHOE|ISIG);
+
+ // input options -> disable flow control
+
+ term.c_iflag&=~(IXON|IXOFF|IXANY);
+
+ // more control options -> timeout
+
+ term.c_cc[VMIN]=0;
+ term.c_cc[VTIME]=10; // 1 second timeout
+
+ tcsetattr(tts_fd,TCSANOW,&term);
+
+ /* auto baud sequence */
+
+ write(tts_fd,"?",1);
+ len=0;
+ txrx(tts_fd,buf,&len,info);
+ if(strncmp(buf,"Synchronized\r\n",14)) {
+ printf("auto baud detection failed\n");
+ return -1;
+ }
+
+ /* tell bl that we are synchronized (it's allready in buf) */
+ len=14;
+ txrx(tts_fd,buf,&len,info);
+ if(strncmp(buf,"OK\r\n",4)) {
+ printf("sync failed\n");
+ return -1;
+ }
+
+ /* tell bl the crystal frequency */
+ len=strlen(cfreq)+2;
+ strncpy(buf,cfreq,BUFSIZE);
+ buf[len-2]='\r';
+ buf[len-1]='\n';
+ txrx(tts_fd,buf,&len,info);
+ if(strncmp(buf,"OK\r\n",4)) {
+ printf("freq set failed\n");
+ return -1;
+ }
+
+
+ // to be continued ... (parsing fw file and poking it to ram)
+
+end:
+ close(tts_fd);
+
+ return 0;
+}
+