00001
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "config.h"
00047 #include "conf_usb.h"
00048
00049 #include "modules/file_system/fat.h"
00050 #include "modules/file_system/fs_com.h"
00051 #include "modules/file_system/navigation.h"
00052 #include "modules/file_system/file.h"
00053 #include "modules/file_system/nav_utils.h"
00054
00055 #include "host_dfu_task.h"
00056 #include "modules/usb/host_chap9/usb_host_task.h"
00057 #include "modules/usb/host_chap9/usb_host_enum.h"
00058 #include "lib_mcu/usb/usb_drv.h"
00059 #include "lib_mcu/flash/flash.h"
00060
00061
00062
00063
00064
00065 #ifndef LOG_STR_CODE
00066 #define LOG_STR_CODE(str)
00067 #else
00068 U8 code log_dfu_connect[]="DFU Connected";
00069 #endif
00070
00071
00072
00073
00074 U8 dfu_connected=0;
00075
00076 static U8 buf[MAX_DATA_PER_RECORD];
00077 static U8 prog_buf[MAX_DATA_PER_RECORD+FLASH_PAGE_SIZE];
00078 static U8 check_buf[MAX_DATA_PER_RECORD+FLASH_PAGE_SIZE];
00079 static U8 dfu_status;
00080
00081 static U16 end_addr;
00082 static U16 start_addr;
00083 static U8 pgm_index=0;
00084 static U8 pgm_nb_data=0;
00085
00086
00087 U8 code firmware_name[]=FIRMWARE_NAME;
00088
00095 void host_dfu_task_init(void)
00096 {
00097 Joy_init();
00098 Leds_init();
00099 dfu_connected=0;
00100 }
00101
00108 void host_dfu_task(void)
00109 {
00110 if(Is_host_ready())
00111 {
00112 if(Is_new_device_connection_event())
00113 {
00114
00115 if(Get_VID()==ATMEL_VID && Get_PID()==AT90DFU_PID)
00116 {
00117 LOG_STR_CODE(log_dfu_connect);
00118 dfu_connected=1;
00119 Led2_on();
00120 }
00121 else
00122 {
00123 dfu_connected=0;
00124 }
00125 }
00126 if(dfu_connected)
00127 {
00128 if(Is_joy_up()||Is_joy_left())
00129 {
00130 nav_reset();
00131 nav_drive_set(0);
00132 if(nav_partition_mount())
00133 {
00134 if(goto_code_name((U8 code *)firmware_name,FALSE,FALSE))
00135 {
00136 Led0_on();
00137 Dfu_erase();
00138 Led0_off();
00139 dfu_load_hex();
00140 }
00141 }
00142 }
00143 }
00144 }
00145
00146
00147 if(Is_device_disconnection_event())
00148 {
00149 dfu_connected=0;
00150 Led2_off();
00151 }
00152 }
00153
00160 U8 dfu_load_hex(void)
00161 {
00162 U8 record_type;
00163 U16 addr;
00164 U8 nb_data;
00165 U8 i;
00166 U8 stop=0;
00167
00168 dfu_status=TRUE;
00169 file_open(FOPEN_MODE_R);
00170 while (file_eof()==FALSE)
00171 {
00172 i=file_getc();
00173 while(i!=RECORD_MARK)
00174 {
00175 i=file_getc();
00176 if(file_eof())
00177 {
00178 stop=1;
00179 break;
00180 }
00181 }
00182 if(stop) break;
00183
00184 nb_data=ascii_to_bin(file_getc());
00185 nb_data=nb_data<<4;
00186 nb_data+=ascii_to_bin(file_getc());
00187 addr=ascii_to_bin(file_getc());
00188 addr=addr<<4;
00189 addr+=ascii_to_bin(file_getc());
00190 addr=addr<<4;
00191 addr+=ascii_to_bin(file_getc());
00192 addr=addr<<4;
00193 addr+=ascii_to_bin(file_getc());
00194 record_type=ascii_to_bin(file_getc());
00195 record_type=record_type<<4;
00196 record_type+=ascii_to_bin(file_getc());
00197 for(i=0;i<nb_data;i++)
00198 {
00199 buf[i]=ascii_to_bin(file_getc());
00200 buf[i]=buf[i]<<4;
00201 buf[i]+=ascii_to_bin(file_getc());
00202 }
00203
00204 switch(record_type)
00205 {
00206 case DATA_RECORD:
00207 if(addr!=end_addr+1 && pgm_index!=0)
00208 {
00209 dfu_flush_prog();
00210 }
00211
00212 for(i=0;i<nb_data;i++)
00213 {
00214 prog_buf[pgm_index]=buf[i];
00215 pgm_index++;
00216 }
00217
00218 pgm_nb_data+=nb_data;
00219
00220 if(pgm_nb_data>nb_data)
00221 {
00222 end_addr=end_addr+nb_data;
00223 }
00224 else
00225 {
00226 end_addr=addr+nb_data-1;
00227 start_addr=addr;
00228 }
00229
00230 if(pgm_index>=10*MAX_DATA_PER_RECORD)
00231 {
00232 dfu_flush_prog();
00233 }
00234 break;
00235 case PAGE_RECORD:
00236 if(pgm_index)
00237 {
00238 dfu_flush_prog();
00239 }
00240 Dfu_set_page(buf[1]);
00241 default:
00242 break;
00243 }
00244 }
00245
00246 if(pgm_index>0)
00247 {
00248 dfu_flush_prog();
00249 }
00250 file_close();
00251 Led0_off();
00252 return dfu_status;
00253 }
00254
00263 void dfu_prog(U16 start,U16 end,U8 *buf)
00264 {
00265 U8 i;
00266 U16 j;
00267 U8 padding;
00268
00269 data_stage[0]=0x01;
00270 data_stage[1]=0;
00271 data_stage[2]=MSB(start);
00272 data_stage[3]=LSB(start);
00273 data_stage[4]=MSB(end);
00274 data_stage[5]=LSB(end);
00275 for(i=6;i<32;i++)
00276 {
00277 data_stage[i]=0;
00278 }
00279 padding=start%32;
00280 j=padding;
00281 while(j)
00282 {
00283 data_stage[i]=0x00;
00284 i++; j--;
00285 }
00286 j=end-start+1;
00287 while(j)
00288 {
00289 data_stage[i]=*buf;
00290 buf++;
00291 j--;i++;
00292 }
00293 Dfu_download(32+end-start+1+padding);
00294 }
00295
00296 void dfu_read(U16 start,U16 end,U8 *buf)
00297 {
00298 U16 j;
00299 U16 i;
00300
00301 data_stage[0]=0x03;
00302 data_stage[1]=0;
00303 data_stage[2]=MSB(start);
00304 data_stage[3]=LSB(start);
00305 data_stage[4]=MSB(end);
00306 data_stage[5]=LSB(end);
00307 Dfu_download(6);
00308 i=end-start+1;
00309 Dfu_upload(i);
00310 for(j=0;j<i;j++)
00311 {
00312 *buf=data_stage[j];
00313 buf++;
00314 }
00315 }
00316
00317 void dfu_flush_prog(void)
00318 {
00319 U8 i;
00320
00321 if( MSB(start_addr)== MSB(end_addr))
00322 {
00323 dfu_prog(start_addr,end_addr,prog_buf);
00324 }
00325 else
00326 {
00327 i=(end_addr%FLASH_PAGE_SIZE);
00328 dfu_prog(start_addr,end_addr-i-1,prog_buf);
00329 dfu_prog(end_addr-i,end_addr,&prog_buf[pgm_nb_data-i-1]);
00330 }
00331
00332 dfu_read(start_addr,end_addr,check_buf);
00333 for(i=0;i<pgm_nb_data;i++)
00334 {
00335 if(prog_buf[i]!=check_buf[i])
00336 {
00337 Leds_on();
00338 dfu_status=FALSE;
00339 }
00340 }
00341 Led0_toggle();
00342 pgm_index=0;
00343 pgm_nb_data=0;
00344 }
00345
00346 U8 ascii_to_bin (U8 b)
00347 {
00348 b|='a'-'A';
00349 return ( (b <= '9') ? (b-'0') : (b+10-'a') );
00350 }
00351