@ -62,9 +62,7 @@ var STM32DFU_protocol = function () {
dfuERROR : 10 // An error has occurred. Awaiting the DFU_CLRSTATUS request.
} ;
this . page _size = 0 ;
this . available _flash _size = 0 ;
this . start _address = 0 ;
this . flash _layout = { 'start_address' : 0 , 'total_size' : 0 , 'sectors' : [ ] } ;
} ;
STM32DFU _protocol . prototype . connect = function ( device , hex , options , callback ) {
@ -257,40 +255,65 @@ STM32DFU_protocol.prototype.getFlashInfo = function (_interface, callback) {
return ;
}
//@Internal Flash /0x08000000/128*0002Kg
// F303: "@Internal Flash /0x08000000/128*0002Kg"
// F407: "@Internal Flash /0x08000000/04*016Kg,01*064Kg,07*128Kg"
// split main into [location, start_addr, sectors]
var tmp1 = str . split ( '/' ) ;
if ( tmp1 . length != 3 ) {
if ( tmp1 . length != 3 || ! tmp1 [ 0 ] . startsWith ( "@Internal Flash" ) ) {
callback ( { } , - 1 ) ;
return ;
}
var tmp2 = tmp1 [ 2 ] . split ( '*' ) ;
if ( tmp2 . length != 2 || tmp2 [ 1 ] . length != 6 ) {
var type = tmp1 [ 0 ] . trim ( ) . replace ( '@' , '' ) ;
var start _address = parseInt ( tmp1 [ 1 ] ) ;
// split sectors into array
var sectors = [ ] ;
var total _size = 0 ;
var tmp2 = tmp1 [ 2 ] . split ( ',' ) ;
if ( tmp2 . length < 1 ) {
callback ( { } , - 2 ) ;
return ;
}
var page _size = parseInt ( tmp2 [ 1 ] . substr ( 0 , 4 ) ) ;
if ( ! page _size ) {
callback ( { } , - 3 ) ;
return ;
}
var unit = tmp2 [ 1 ] . substr ( 4 , 1 ) ;
switch ( unit ) {
case 'M' :
page _size *= 1024 ; // fall through to K as well
case 'K' :
page _size *= 1024 ;
break ;
default :
for ( var i = 0 ; i < tmp2 . length ; i ++ ) {
// split into [num_pages, page_size]
var tmp3 = tmp2 [ i ] . split ( '*' ) ;
if ( tmp3 . length != 2 ) {
callback ( { } , - 3 ) ;
return ;
}
var num _pages = parseInt ( tmp3 [ 0 ] ) ;
var page _size = parseInt ( tmp3 [ 1 ] ) ;
if ( ! page _size ) {
callback ( { } , - 4 ) ;
return ;
}
var unit = tmp3 [ 1 ] . slice ( - 2 , - 1 ) ;
switch ( unit ) {
case 'M' :
page _size *= 1024 ; // fall through to K as well
case 'K' :
page _size *= 1024 ;
break ;
default :
callback ( { } , - 4 ) ;
return ;
}
sectors . push ( {
'num_pages' : num _pages ,
'start_address' : start _address + total _size ,
'page_size' : page _size ,
'total_size' : num _pages * page _size
} ) ;
total _size += num _pages * page _size ;
}
var flash = {
'start_address' : parseInt ( tmp1 [ 1 ] ) ,
'num_pages' : parseInt ( tmp2 [ 0 ] ) ,
'page_size' : page _size ,
'total_size' : parseInt ( tmp2 [ 0 ] ) * page _size
' type' : type ,
' start_address': start _address ,
' sectors ' : sectors ,
'total_size' : total _size
}
callback ( flash , resultCode ) ;
@ -424,12 +447,10 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
console . log ( 'Failed to detect chip flash info, resultCode: ' + resultCode ) ;
self . upload _procedure ( 99 ) ;
} else {
self . page _size = flash . page _size ;
self . start _address = flash . start _address ;
self . available _flash _size = flash . total _size - ( self . hex . start _linear _address - self . start _address ) ;
self . flash _layout = flash ;
self . available _flash _size = flash . total _size - ( self . hex . start _linear _address - flash . start _address ) ;
GUI . log ( chrome . i18n . getMessage ( 'dfu_device_flash_info' , [ flash . num _pages . toString ( ) ,
( flash . page _size / 1024 ) . toString ( ) , ( flash . total _size / 1024 ) . toString ( ) ] ) ) ;
GUI . log ( chrome . i18n . getMessage ( 'dfu_device_flash_info' , ( flash . total _size / 1024 ) . toString ( ) ) ) ;
if ( self . hex . bytes _total > self . available _flash _size ) {
GUI . log ( chrome . i18n . getMessage ( 'dfu_error_image_size' ,
@ -475,17 +496,41 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
} else {
// local erase
var max _address = self . hex . data [ self . hex . data . length - 1 ] . address + self . hex . data [ self . hex . data . length - 1 ] . bytes - 0x8000000 ,
erase _pages _n = Math . ceil ( max _address / self . page _size ) ,
page = 0 ;
// find out which pages to erase
var erase _pages = [ ] ;
for ( var i = 0 ; i < self . flash _layout . sectors . length ; i ++ ) {
for ( var j = 0 ; j < self . flash _layout . sectors [ i ] . num _pages ; j ++ ) {
var page _start = self . flash _layout . sectors [ i ] . start _address + j * self . flash _layout . sectors [ i ] . page _size ;
var page _end = page _start + self . flash _layout . sectors [ i ] . page _size - 1 ;
for ( var k = 0 ; k < self . hex . data . length ; k ++ ) {
var starts _in _page = self . hex . data [ k ] . address >= page _start && self . hex . data [ k ] . address <= page _end ;
var end _address = self . hex . data [ k ] . address + self . hex . data [ k ] . bytes - 1 ;
var ends _in _page = end _address >= page _start && end _address <= page _end ;
var spans _page = self . hex . data [ k ] . address < page _start && end _address > page _end ;
if ( starts _in _page || ends _in _page || spans _page ) {
var idx = erase _pages . findIndex ( function ( element , index , array ) {
return element . sector == i && element . page == j ;
} ) ;
if ( idx == - 1 )
erase _pages . push ( { 'sector' : i , 'page' : j } ) ;
}
}
}
}
$ ( 'span.progressLabel' ) . text ( 'Erasing ...' ) ;
console . log ( 'Executing local chip erase' ) ;
console . log ( 'Erasing. page: 0x00 - 0x' + erase _pages _n . toString ( 16 ) ) ;
console . log ( 'Executing local chip erase' ) ;
var page = 0 ;
var total _erased = 0 ; // bytes
var erase _page = function ( ) {
var page _addr = page * self . page _size + self . hex . start _linear _address ;
var page _addr = erase _pages [ page ] . page * self . flash _layout . sectors [ erase _pages [ page ] . sector ] . page _size +
self . flash _layout . sectors [ erase _pages [ page ] . sector ] . start _address ;
var cmd = [ 0x41 , page _addr & 0xff , ( page _addr >> 8 ) & 0xff , ( page _addr >> 16 ) & 0xff , ( page _addr >> 24 ) & 0xff ] ;
total _erased += self . flash _layout . sectors [ erase _pages [ page ] . sector ] . page _size ;
console . log ( 'Erasing. sector ' + erase _pages [ page ] . sector +
', page ' + erase _pages [ page ] . page + ' @ 0x' + page _addr . toString ( 16 ) ) ;
self . controlTransfer ( 'out' , self . request . DNLOAD , 0 , 0 , 0 , cmd , function ( ) {
self . controlTransfer ( 'in' , self . request . GETSTATUS , 0 , 0 , 6 , 0 , function ( data ) {
@ -496,24 +541,24 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
self . controlTransfer ( 'in' , self . request . GETSTATUS , 0 , 0 , 6 , 0 , function ( data ) {
if ( data [ 4 ] == self . state . dfuDNLOAD _IDLE ) {
// update progress bar
self . progress _bar _e . val ( ( page + 1 ) / erase _pages _n * 100 ) ;
self . progress _bar _e . val ( ( page + 1 ) / erase _pages . length * 100 ) ;
page ++ ;
if ( page == erase _pages _n ) {
if ( page == erase _pages . length ) {
console . log ( "Erase: complete" ) ;
GUI . log ( chrome . i18n . getMessage ( 'dfu_erased_kilobytes' , ( erase_pages _n * self . page _size / 1024 ) . toString ( ) ) ) ;
GUI . log ( chrome . i18n . getMessage ( 'dfu_erased_kilobytes' , ( total_erased / 1024 ) . toString ( ) ) ) ;
self . upload _procedure ( 4 ) ;
}
else
erase _page ( ) ;
} else {
console . log ( 'Failed to erase page 0x' + self. current _page . toString ( 16 ) ) ;
console . log ( 'Failed to erase page 0x' + page_addr . toString ( 16 ) ) ;
self . upload _procedure ( 99 ) ;
}
} ) ;
} , delay ) ;
} else {
console . log ( 'Failed to initiate page erase, page 0x' + self. current _page . toString ( 16 ) ) ;
console . log ( 'Failed to initiate page erase, page 0x' + page_addr . toString ( 16 ) ) ;
self . upload _procedure ( 99 ) ;
}
} ) ;