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
00075 U8 dfu_connected=0;
00076
00077 static U8 buf[MAX_DATA_PER_RECORD];
00078 static U8 prog_buf[MAX_DATA_PER_RECORD+FLASH_PAGE_SIZE];
00079 static U8 check_buf[MAX_DATA_PER_RECORD+FLASH_PAGE_SIZE];
00080 static U8 dfu_status;
00081
00082 static U16 end_addr;
00083 static U16 start_addr;
00084 static U8 pgm_index=0;
00085 static U8 pgm_nb_data=0;
00086
00087
00088 U8 code firmware_name[]=FIRMWARE_NAME;
00089
00096 void host_dfu_task_init(void)
00097 {
00098 Joy_init();
00099 Leds_init();
00100 dfu_connected=0;
00101 }
00102
00109 void host_dfu_task(void)
00110 {
00111 if(Is_host_ready())
00112 {
00113 if(Is_new_device_connection_event())
00114 {
00115
00116 if(Get_VID()==ATMEL_VID && Get_PID()==AT90DFU_PID)
00117 {
00118 LOG_STR_CODE(log_dfu_connect);
00119 dfu_connected=1;
00120 Led1_on();
00121 }
00122 else
00123 {
00124 dfu_connected=0;
00125 }
00126 }
00127 if(dfu_connected)
00128 {
00129 if(Is_joy_up()||Is_joy_left())
00130 {
00131 nav_reset();
00132 nav_drive_set(0);
00133 if(nav_partition_mount())
00134 {
00135 if(goto_code_name((U8 code *)firmware_name,FALSE,TRUE))
00136 {
00137 Led0_on();
00138 Dfu_erase();
00139 Led0_off();
00140 dfu_load_hex();
00141 }
00142 }
00143 }
00144 }
00145 }
00146
00147
00148 if(Is_device_disconnection_event())
00149 {
00150 dfu_connected=0;
00151 Led1_off();
00152 }
00153 }
00154
00161 U8 dfu_load_hex(void)
00162 {
00163 U8 record_type;
00164 U16 addr;
00165 U8 nb_data;
00166 U8 i;
00167 U8 stop=0;
00168
00169 dfu_status=TRUE;
00170 file_open(FOPEN_MODE_R);
00171 while (file_eof()==FALSE)
00172 {
00173 i=file_getc();
00174 while(i!=RECORD_MARK)
00175 {
00176 i=file_getc();
00177 if(file_eof())
00178 {
00179 stop=1;
00180 break;
00181 }
00182 }
00183 if(stop) break;
00184
00185 nb_data=ascii_to_bin(file_getc());
00186 nb_data=nb_data<<4;
00187 nb_data+=ascii_to_bin(file_getc());
00188 addr=ascii_to_bin(file_getc());
00189 addr=addr<<4;
00190 addr+=ascii_to_bin(file_getc());
00191 addr=addr<<4;
00192 addr+=ascii_to_bin(file_getc());
00193 addr=addr<<4;
00194 addr+=ascii_to_bin(file_getc());
00195 record_type=ascii_to_bin(file_getc());
00196 record_type=record_type<<4;
00197 record_type+=ascii_to_bin(file_getc());
00198 for(i=0;i<nb_data;i++)
00199 {
00200 buf[i]=ascii_to_bin(file_getc());
00201 buf[i]=buf[i]<<4;
00202 buf[i]+=ascii_to_bin(file_getc());
00203 }
00204
00205 switch(record_type)
00206 {
00207 case DATA_RECORD:
00208 if(addr!=end_addr+1 && pgm_index!=0)
00209 {
00210 dfu_flush_prog();
00211 }
00212
00213 for(i=0;i<nb_data;i++)
00214 {
00215 prog_buf[pgm_index]=buf[i];
00216 pgm_index++;
00217 }
00218
00219 pgm_nb_data+=nb_data;
00220
00221 if(pgm_nb_data>nb_data)
00222 {
00223 end_addr=end_addr+nb_data;
00224 }
00225 else
00226 {
00227 end_addr=addr+nb_data-1;
00228 start_addr=addr;
00229 }
00230
00231 if(pgm_index>=10*MAX_DATA_PER_RECORD)
00232 {
00233 dfu_flush_prog();
00234 }
00235 break;
00236 case PAGE_RECORD:
00237 if(pgm_index)
00238 {
00239 dfu_flush_prog();
00240 }
00241 Dfu_set_page(buf[1]);
00242 default:
00243 break;
00244 }
00245 }
00246
00247 if(pgm_index>0)
00248 {
00249 dfu_flush_prog();
00250 }
00251 file_close();
00252 Led0_off();
00253 return dfu_status;
00254 }
00255
00264 void dfu_prog(U16 start,U16 end,U8 *buf)
00265 {
00266 U8 i;
00267 U16 j;
00268 U8 padding;
00269
00270 data_stage[0]=0x01;
00271 data_stage[1]=0;
00272 data_stage[2]=MSB(start);
00273 data_stage[3]=LSB(start);
00274 data_stage[4]=MSB(end);
00275 data_stage[5]=LSB(end);
00276 for(i=6;i<32;i++)
00277 {
00278 data_stage[i]=0;
00279 }
00280 padding=start%32;
00281 j=padding;
00282 while(j)
00283 {
00284 data_stage[i]=0x00;
00285 i++; j--;
00286 }
00287 j=end-start+1;
00288 while(j)
00289 {
00290 data_stage[i]=*buf;
00291 buf++;
00292 j--;i++;
00293 }
00294 Dfu_download(32+end-start+1+padding);
00295 }
00296
00297 void dfu_read(U16 start,U16 end,U8 *buf)
00298 {
00299 U16 j;
00300 U16 i;
00301
00302 data_stage[0]=0x03;
00303 data_stage[1]=0;
00304 data_stage[2]=MSB(start);
00305 data_stage[3]=LSB(start);
00306 data_stage[4]=MSB(end);
00307 data_stage[5]=LSB(end);
00308 Dfu_download(6);
00309 i=end-start+1;
00310 Dfu_upload(i);
00311 for(j=0;j<i;j++)
00312 {
00313 *buf=data_stage[j];
00314 buf++;
00315 }
00316 }
00317
00318 void dfu_flush_prog(void)
00319 {
00320 U8 i;
00321
00322 if( MSB(start_addr)== MSB(end_addr))
00323 {
00324 dfu_prog(start_addr,end_addr,prog_buf);
00325 }
00326 else
00327 {
00328 i=(end_addr%FLASH_PAGE_SIZE);
00329 dfu_prog(start_addr,end_addr-i-1,prog_buf);
00330 dfu_prog(end_addr-i,end_addr,&prog_buf[pgm_nb_data-i-1]);
00331 }
00332
00333 dfu_read(start_addr,end_addr,check_buf);
00334 for(i=0;i<pgm_nb_data;i++)
00335 {
00336 if(prog_buf[i]!=check_buf[i])
00337 {
00338 Leds_on();
00339 dfu_status=FALSE;
00340 }
00341 }
00342 Led0_toggle();
00343 pgm_index=0;
00344 pgm_nb_data=0;
00345 }
00346
00347 U8 ascii_to_bin (U8 b)
00348 {
00349 b|='a'-'A';
00350 return ( (b <= '9') ? (b-'0') : (b+10-'a') );
00351 }
00352