OSDN Git Service

lejos_NXJ_win32_0_5_0beta.zip
[nxt-jsp/lejos_nxj.git] / nxtOSEK / lejos_nxj / src / libnxt / firmware.c
1 /**
2  * NXT bootstrap interface; NXT firmware handling code.
3  *
4  * Copyright 2006 David Anderson <david.anderson@calixo.net>
5  * Modified 2007 by Lawrie Griffiths <lawrie.griffiths@ntlworld.com> 
6  * to support lejos NXJ firmware flashing.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21  * USA
22  */
23
24 #include <stdio.h>
25 #include <errno.h>
26 #include <string.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31
32 #include "error.h"
33 #include "lowlevel.h"
34 #include "samba.h"
35 #include "flash.h"
36 #include "firmware.h"
37 #include "flash_routine.h"
38
39 static nxt_error_t
40 nxt_flash_prepare(nxt_t *nxt, int unlock)
41 {
42   // Put the clock in PLL/2 mode
43   NXT_ERR(nxt_write_word(nxt, 0xFFFFFC30, 0x7));
44
45   // Unlock the flash chip
46   if (unlock) NXT_ERR(nxt_flash_unlock_all_regions(nxt));
47
48   // Send the flash writing routine
49   NXT_ERR(nxt_send_file(nxt, 0x202000, flash_bin, flash_len));
50
51   return NXT_OK;
52 }
53
54
55 static nxt_error_t
56 nxt_flash_block(nxt_t *nxt, nxt_word_t block_num, char *buf)
57 {
58   // Set the target block number
59   NXT_ERR(nxt_write_word(nxt, 0x202300, block_num));
60
61   // Send the block to flash
62   NXT_ERR(nxt_send_file(nxt, 0x202100, buf, 256));
63
64   // Jump into the flash writing routine
65   NXT_ERR(nxt_jump(nxt, 0x202000));
66
67   return NXT_OK;
68 }
69
70
71 static nxt_error_t
72 nxt_flash_finish(nxt_t *nxt)
73 {
74   return nxt_flash_wait_ready(nxt);
75 }
76
77
78 static nxt_error_t
79 nxt_firmware_validate_fd(int fd, int max_size)
80 {
81   struct stat s;
82
83   if (fstat(fd, &s) < 0)
84     return NXT_FILE_ERROR;
85
86   if (s.st_size > max_size)
87     return NXT_INVALID_FIRMWARE;
88
89   return NXT_OK;
90 }
91
92
93 nxt_error_t
94 nxt_firmware_validate(char *fw_path, int max_pages)
95 {
96   nxt_error_t err;
97   int fd;
98
99 #if defined(_WIN32) || defined(__CYGWIN32__)
100   fd = open(fw_path, O_RDONLY | O_BINARY);
101 #else
102   fd = open(fw_path, O_RDONLY);
103 #endif
104   if (fd < 0)
105     return NXT_FILE_ERROR;
106
107   err = nxt_firmware_validate_fd(fd, max_pages * 256);
108   close(fd);
109
110   return err;
111 }
112
113
114 nxt_error_t
115 nxt_firmware_flash(nxt_t *nxt, char *fw_path, 
116                    int start_page, int max_pages, int unlock, int write_len)
117 {
118   int fd, i, err, len = 0;
119   char buf[256];
120
121 #if defined(_WIN32) || defined(__CYGWIN32__)
122   fd = open(fw_path, O_RDONLY | O_BINARY);
123 #else
124   fd = open(fw_path, O_RDONLY);
125 #endif
126   if (fd < 0)
127     return NXT_FILE_ERROR;
128
129   err = nxt_firmware_validate_fd(fd, max_pages * 256);
130   if (err != NXT_OK)
131     {
132       close(fd);
133       return NXT_INVALID_FIRMWARE;
134     }
135
136   NXT_ERR(nxt_flash_prepare(nxt, unlock));
137
138   for (i = start_page; i < start_page + max_pages; i++) 
139     {
140
141       int ret;
142
143       memset(buf, 0, 256);
144       ret = read(fd, buf, 256);
145
146       if (ret != -1) 
147         {
148           NXT_ERR(nxt_flash_block(nxt, i, buf));
149           len += ret;
150         }
151
152       if (ret < 256)
153         {
154           close(fd);
155         
156           if (ret != -1 && write_len)
157             {
158               ((unsigned *) buf)[63] = len;
159               NXT_ERR(nxt_flash_block(nxt,start_page + max_pages -1, buf));
160             }
161
162           NXT_ERR(nxt_flash_finish(nxt));
163           
164           return ret == -1 ? NXT_FILE_ERROR : NXT_OK;
165         }
166     }
167
168   close(fd);
169   
170   if (write_len) 
171     { 
172       ((unsigned *) buf)[63] = len;
173       NXT_ERR(nxt_flash_block(nxt,start_page + max_pages -1, buf));
174     }
175   
176   NXT_ERR(nxt_flash_finish(nxt));
177
178   return NXT_OK;
179 }
180