2 * lpcload.c - load firmware into ram of lpc2220 via uart0
4 * author: hackbard@hackdaworld.org
12 #include <sys/types.h>
17 #define VERBOSE (1<<0)
18 #define FIRMWARE (1<<1)
20 #define TXRX_TYPE_BAUD 0x01
21 #define TXRX_TYPE_SYNC 0x02
22 #define TXRX_TYPE_DATA 0x03
24 #define CMD_SUCCESS "0\r\n"
25 #define INVALID_COMMAND "1\r\n"
26 #define SRC_ADDR_ERROR "2\r\n"
27 #define DST_ADDR_ERROR "3\r\n"
28 #define SRC_ADDR_NOT_MAPPED "4\r\n"
29 #define DST_ADDR_NOT_MAPPED "5\r\n"
30 #define COUNT_ERROR "6\r\n"
31 #define COMPARE_ERROR "10\r\n"
33 #define PARAM_ERROR "12\r\n"
34 #define ADDR_ERROR "13\r\n"
35 #define ADDR_NOT_MAPPED "14\r\n"
36 #define CMD_LOCKED "15\r\n"
37 #define INVALID_CODE "16\r\n"
38 #define INVALID_BAUD_RATE "17\r\n"
39 #define INVALID_STOP_BIT "18\r\n"
41 #define CRYSTFREQ "10000"
45 typedef unsigned char u8;
47 typedef struct s_lpc {
48 int sfd; /* serial fd */
49 char sdev[128]; /* seriel device */
50 int fwfd; /* fimrware fd */
51 char fwfile[128]; /* firmware file */
52 u8 info; /* info/mode */
53 char freq[8]; /* frequency */
54 int partid; /* part id */
55 u8 bcv[2]; /* boot code version */
60 printf("possible argv:\n");
61 printf(" -d <serial device>\n");
62 printf(" -f <firmware>\n");
63 printf(" -c <crystal freq>\n");
68 int open_serial_device(t_lpc *lpc) {
72 //memset(&term,0,sizeof(struct termios));
74 /* open serial device */
76 lpc->sfd=open(lpc->sdev,O_RDWR);
82 /* configure the serial device */
84 tcgetattr(lpc->sfd,&term);
86 // input/output baudrate
88 cfsetispeed(&term,B9600);
89 cfsetospeed(&term,B9600);
91 // control options -> 8n1
93 term.c_cflag&=~PARENB; // no parity
94 term.c_cflag&=~CSTOPB; // only 1 stop bit
95 term.c_cflag&=~CSIZE; // no bit mask for data bits
96 term.c_cflag|=CS8; // 8 data bits
98 // line options -> raw input
100 term.c_lflag&=~(ICANON|ECHO|ECHOE|ISIG);
102 // input options -> disable flow control
104 term.c_iflag&=~(IXON|IXOFF|IXANY);
106 // more control options -> timeout
109 term.c_cc[VTIME]=10; // 1 second timeout
111 tcsetattr(lpc->sfd,TCSANOW,&term);
116 int open_firmware(t_lpc *lpc) {
118 /* open firmware file */
120 lpc->fwfd=open(lpc->fwfile,O_RDONLY);
128 int txrx(t_lpc *lpc,char *buf,int len,u8 type) {
135 if(lpc->info&VERBOSE)
139 ret=write(lpc->sfd,buf+cnt,len);
141 perror("txrx write");
144 if(lpc->info&VERBOSE)
147 ((buf[cnt+i]>0x19)&(buf[cnt+i]<0x7f))?
152 if(lpc->info&VERBOSE)
153 printf(" (%d)\n",cnt);
155 /* cut the echo if not of type auto baud */
157 if(type!=TXRX_TYPE_BAUD) {
159 ret=read(lpc->sfd,buf,cnt);
161 perror("txrx echo cut");
170 if(lpc->info&VERBOSE)
175 ret=read(lpc->sfd,buf+cnt,BUFSIZE-cnt);
180 if(ret+cnt>BUFSIZE) {
181 printf("txrx read: too small buf size (%d)!\n",BUFSIZE);
184 if(lpc->info&VERBOSE)
187 ((buf[cnt+i]>0x19)&(buf[cnt+i]<0x7f))?
191 if(lpc->info&VERBOSE)
192 printf(" (%d)\n",cnt);
196 /* check/strip return code if type is data */
198 if(type==TXRX_TYPE_DATA) {
199 ret=strlen(CMD_SUCCESS);
200 if(!strncmp(buf,CMD_SUCCESS,ret)) {
206 printf("txrx bad return code!\n");
214 int bl_init(t_lpc *lpc) {
219 /* auto baud sequence */
221 txrx(lpc,buf,1,TXRX_TYPE_BAUD);
222 if(strncmp(buf,"Synchronized\r\n",14)) {
223 printf("auto baud detection failed\n");
227 /* tell bl that we are synchronized (it's allready in buf) */
228 txrx(lpc,buf,14,TXRX_TYPE_SYNC);
229 if(strncmp(buf,"OK\r\n",4)) {
230 printf("sync failed\n");
234 /* tell bl the crystal frequency */
235 len=strlen(lpc->freq)+2;
236 strncpy(buf,lpc->freq,BUFSIZE);
239 txrx(lpc,buf,len,TXRX_TYPE_SYNC);
240 if(strncmp(buf,"OK\r\n",4)) {
241 printf("freq set failed\n");
248 int read_part_id(t_lpc *lpc) {
252 memcpy(buf,"J\r\n",3);
253 txrx(lpc,buf,3,TXRX_TYPE_DATA);
254 lpc->partid=atoi(buf);
259 int read_bcv(t_lpc *lpc) {
264 memcpy(buf,"K\r\n",3);
265 txrx(lpc,buf,3,TXRX_TYPE_DATA);
266 ptr=strtok(buf,"\r\n");
267 lpc->bcv[0]=strtol(ptr,NULL,16);
268 ptr=strtok(NULL,"\r\n");
269 lpc->bcv[1]=strtol(ptr,NULL,16);
274 int main(int argc,char **argv) {
283 memset(&lpc,0,sizeof(t_lpc));
284 strncpy(lpc.freq,CRYSTFREQ,7);
288 for(i=1;i<argc;i++) {
290 if(argv[i][0]!='-') {
297 strncpy(lpc.sdev,argv[++i],127);
300 strncpy(lpc.fwfile,argv[++i],127);
307 strncpy(lpc.freq,argv[++i],7);
316 /* open serial port */
317 open_serial_device(&lpc);
319 /* boot loader init */
320 printf("boot loader init ...\n");
325 printf("part id: %d\n",lpc.partid);
327 /* read boot code version */
329 printf("boot code version: %02x %02x\n",lpc.bcv[0],lpc.bcv[1]);
331 // to be continued ... (parsing fw file and poking it to ram)