this transfers data (which is stored in "bin" file in mbed storage) into LPC1114, LPC1115, LPC81x, LPC82x, LPC1768/LPC1769 and LPC11U68/LPC11E68 internal flash memory through ISP.

Dependencies:   mbed MODSERIAL DirectoryList

Information

日本語版がこのページ下半分にあります!

Japanese version is available lower half of this page.

Caution!

このプログラムでイカを焼くことはできません (^ ^;

"Ika-shouyu-poppoyaki" is a name of Japanese local food.
If I try to do a direct translation, it will be something like "Choo-choo grilled calamari with soy-sauce".
However, you may noticed already, it cannot be grilled by this program ;-)

ISP programming application on mbed

ISP program writes data into flash memory of target MCU.

This mbed program programs target MCU flash memory through UART. It uses "In-System Programming (ISP)" interface in target MCU (NXP LPC micro-controllers).

The ISP is done by PC with serial cable normally. The ISP protocol is executed software on a PC. The software reads a data file and transfers the data with the ISP protocol.
This program does same process of that. The mbed performs a function like "FlashMagic" or "lpc21isp".
(This program does not just copy the binary but also insert 4 byte checksum at address 0x1C.)

This program currently supports LPC1114, LPC1115, LPC81x, LPC82x, LPC1768/LPC1769 and LPC11U68/LPC11E68.

Information

For the LPC1768 and LPC1769, this program supports writing only. It cannot perform verifying.

Modification for targeting LPC82x series has been done by Mr. k4zuki. Thank you very much!
Modification for targeting LPC11U68/LPC11E68 has been done by HAPI- Tech. Thank you very much!!

/media/uploads/okano/copying_bin_e.png

How to execute

With this program, all you need to do is..

  1. Connect the mbed and the target (/RESET and /ISP_enable signals in are option. Those are not necessary if you set the target ISP mode manually)
  2. Rename your (binary) file to "bin" and copy into the mbed storage.
  3. Press reset button of mbed.
  • When the program completed successfully, you will find the LEDs on mbed blinks sequentially (LED1→LED2→LED3→LED4).
  • If it failed, the mbed reports it "Runtime error" by LEDs.
  • You can also monitor the progress and result on a terminal screen (mbed reports those by printf).
  • if you enabled "AUTO_PROGRAM_START", the program in the target will be started automatically.
  • from version 0.7, this program works as "USB-serial bridge" after the ISP writing done. The serial enabled target program (and if "AUTO_PROGRAM_START" is enabled, ) the UART will come up on the terminal screen after ISP completion. Please set "TARGET_OPERATION_BAUD_RATE" as baud rate of target program. The ISP speed can be set by "ISP_BAUD_RATE" separately.

/media/uploads/okano/files_in_storage_e.png

Information

If you don't have a file named "bin", the program will ask you which file you want to choose.
You will find a list of files on PC terminal and that interface let you select a file as source.
(The file names will appear in 8.3 format like old DOS.)

There are some options to bypassing the ISP to execute USB-serial through mode or erasing flash.

If there is a "bin" file, the program may work as usual.
(updated on 29-Jan-2015)

Sample of operation

Next picture is sample of the operation.

  1. The target (LPC1114) goes into ISP mode after first reset.
  2. mbed writes binary into flash in the target (binary size is 12668 bytes in this sample).
  3. when the writing completed, mbed starts reading the flash. the data is verified by comparing with original file.
  4. Asserting reset again with "ISP_enable pin" HIGH.
  5. The target starts to work with written binary (program). In this sample, the target sending character data on UART and toggling LED (GPIO) pin periodically.

/media/uploads/okano/isp_operation_sample_1114_e2.png

Recipe for adding chip support

Information

This section had been written by At_Zamasu_Zansu.
Thank you!

Describing how to add a target device.
Register new Device ID in target_table.cpp.

Targets defined in target_table.cpp.

target_table.cpp

target_param    target_table[]  = {
    { "unknown ttarget",        0xFFFFFFFF, 1024,    4096, 4096, UUENCODE, 0x10000200 },
    { "LPC1114FN28(FDH28)/102", 0x0A40902B, 4096,   32768, 4096, UUENCODE, 0x10000200 },
    { "LPC1114FN28(FDH28)/102", 0x1A40902B, 4096,   32768, 4096, UUENCODE, 0x10000200 },
    { "LPC810M021FN8",          0x00008100, 1024,    4096, 1024, BINARY,   0x10000300 },
    { "LPC811M001JDH16",        0x00008110, 2048,    8192, 1024, BINARY,   0x10000300 },
    { "LPC812M101JDH16",        0x00008120, 4096,   16384, 1024, BINARY,   0x10000300 },
    { "LPC812M101JD20",         0x00008121, 4096,   16384, 1024, BINARY,   0x10000300 },
    { "LPC812M101JDH20",        0x00008122, 4096,   16384, 1024, BINARY,   0x10000300 },
///added for LPC82x series
    { "LPC824M201JHI33",        0x00008241, 8192,   32768, 1024, BINARY,   0x10000300 },
    { "LPC822M101JHI33",        0x00008221, 4096,   16384, 1024, BINARY,   0x10000300 },
    { "LPC824M201JDH20",        0x00008242, 8192,   32768, 1024, BINARY,   0x10000300 },
    { "LPC822M101JDH20",        0x00008222, 4096,   16384, 1024, BINARY,   0x10000300 },
 
};

Structure of the table is defined in target_table.h.

target_table.h

typedef struct  taget_param_st {
    char            *type_name;
    int             id;
    int             ram_size;
    int             flash_size;
    int             sector_size;
    int             write_type;
    unsigned int    ram_start_address;
}

Items are defined in order of next sample in target_table.cpp

 {type_name, id, ram_size, flash_size, sector_size, write_type, ram_start_address}

Sample of how to do this

Data can be found in usermanual(UM) and datasheet. An example following.

In case of LPC82xx
UM10800 LPC82x User manual http://www.nxp.com/documents/user_manual/UM10800.pdf
LPC82x Product data sheet http://www.nxp.com/documents/data_sheet/LPC82X.pdf

  • type_name:
    • Table 322. Part identification numbers can be found by searching in UM. Pick up a device from the Table 322.
  • id:
    • Put a Hex coding value in Table 322.
  • ram_size:
    • Put target RAM size which can be found in datasheet by searching "Ordering options". Find the RAM size in Table2 (in bytes)
  • flash_size:
    • Put target flash size from the Table 2.
      The size should be calculated as "1KB = 1024" bytes.
  • sector_size:
    • A description of "The size of a sector is 1 KB and the size of a page is 64 Byte. One sector contains 16 pages" can be found in 25.5 General description, UM. Pick up taeget sector size and put it into the table in bytes. In this case, it will be 1024.
    • In case of LPC176x, the secotr size is 4KB for first 16 sectors and rest are 32K. So it cannot be defined by single value. For this type of targets, prepare a special value for the sector size. The program calculates the size when this value is detected.
  • ram_start_address:
    • Put an address of example which can be found by searching "UART ISP Write to RAM command" or "Write to RAM" in UM

Reference




イカ醤油ポッポ焼き

mbed用ISPプログラム

NXP製のマイコンは,内部フラッシュメモリへのプログラムの書き込みをUART経由で行うことができます.
通常,この作業はPC上のソフトウェア(たとえば"FlashMagic""lpc21isp"など)を用いて,PC上のファイルのデータを,UARTで接続したマイコンの内蔵フラッシュに書き込みます.

「イカ醤油ポッポ焼き」はmbedでそれらのソフトの代わりをさせるものです.mbedストレージ内に置いた「bin」と名付けられたファイルを読み,フラッシュへ書き込みます.
この書き込みを行う際には,アドレス0x1Cに置いておく必要のある4バイトのチェックサムも自動で追加されます.

現在サポートしているターゲットはLPC1114LPC1115LPC81xLPC82xLPC1768/LPC1769LPC11U68/LPC11E68です.

Information

LPC1768 and LPC1769 では書き込みのみがサポートされます.読み出し検証は実行されません.

LPC82xシリーズをターゲットとするための変更k4zukiさんがしてくださいました.ありがとうございます!
LPC11U68/LPC11E68をターゲットとするための変更HAPI- Techさんがしてくださいました.ありがとうございます!

/media/uploads/okano/copying_bin_j.png

美味しい料理法

このプログラムの動かし方は次の通り

  1. mbedとターゲット(書き込み対象のマイコン)を接続する (ターゲットを手動でISPモードに入れる場合には,/RESET と /ISP_enable は接続する必要はありません)
  2. 書き込みたいファイル(バイナリフォーマット)の名前を「bin」に変更して,mbed内にコピー
  3. mbedのリセットボタンを押す
  • 書き込みが無事に終了するとmbed上のLEDが順番に点滅を繰り返します(LED1→LED2→LED3→LED4).
  • もし何らかのエラーが発生して失敗した場合には"Runtime error"が発生した時のLED点灯となります.
  • またコンピュータのターミナルで状況や結果を確認することもできます(mbedがprintfで状況を出力しています)
  • "AUTO_PROGRAM_START"を有効にしてあれば,書き込み終了後,ターゲットのプログラムは自動的にスタートします.
  • バージョン0.7以降,このプログラムはISP書き込みの終了後にUSB-Serialブリッジとして動作するようにしてあります.ターゲットのプログラムがシリアルを使うもので(かつ"AUTO_PROGRAM_START"が有効で)あれば,入出力はそのままISP完了後のターミナルに現れます."TARGET_OPERATION_BAUD_RATE"はターゲットのプログラムが使うボーレートに合わせてください.ISPの書き込みに使うボーレートは "これとは別に"ISP_BAUD_RATE"で指定することができます.

/media/uploads/okano/files_in_storage_j2.png

Information

もし「bin」と名付けられたファイルが見つからなければ,(PCターミナル上で)どのファイルを選択するかが訊ねられます.
その表示を確認して,どのファイルを書き込むのかを選択してください.
「bin」ファイルが有れば,これまでと同じように動作します.(ファイル名はDOSのような8.3フォーマットで表示されます)

この他,ISPをバイパスしてシリアススルー・モードに行ったり,フラッシュを消すだけという操作も可能になっています.

(2015年1月29日にアップデートされました)

動作の例

次の図は動作の例です

  1. 最初のリセットによってターゲット(LPC1114)がISPモードに入ります
  2. mbedがターゲットのフラッシュにバイナリを書き込みます(この例では12668バイトのバイナリを書いています)
  3. 書き込みが終わるとフラッシュの読み出しを始めます.このデータを元のファイルとの比較し,検証を行います
  4. ISPイネーブル・ピンをHIGHにして再度リセットを行います
  5. ターゲットは書き込まれたプログラムの実行を開始します.この例ではターゲットは周期的にUARTへ文字データを送り,LEDを(GPIOピン)を点滅させます
  6. The target starts to work with written binary (program). The target sending character data on UART and toggling LED (GPIO) pin periodically.

/media/uploads/okano/isp_operation_sample_1114_j2.png


イカ醤油ポッポ焼き味付けレシピ

Information

この節はざますざんすさんが作成してくれました.
ありがとうございます!

これは,イカ醤油ポッポ焼きに新しいターゲットデバイスを追加する場合のレシピを纏めたものです.

必要事項:target_table.cpp へ新しいDevice ID register を追加する.

target_table.cppに記載されているターゲット一覧.

target_table.cpp

target_param    target_table[]  = {
    { "unknown ttarget",        0xFFFFFFFF, 1024,    4096, 4096, UUENCODE, 0x10000200 },
    { "LPC1114FN28(FDH28)/102", 0x0A40902B, 4096,   32768, 4096, UUENCODE, 0x10000200 },
    { "LPC1114FN28(FDH28)/102", 0x1A40902B, 4096,   32768, 4096, UUENCODE, 0x10000200 },
    { "LPC810M021FN8",          0x00008100, 1024,    4096, 1024, BINARY,   0x10000300 },
    { "LPC811M001JDH16",        0x00008110, 2048,    8192, 1024, BINARY,   0x10000300 },
    { "LPC812M101JDH16",        0x00008120, 4096,   16384, 1024, BINARY,   0x10000300 },
    { "LPC812M101JD20",         0x00008121, 4096,   16384, 1024, BINARY,   0x10000300 },
    { "LPC812M101JDH20",        0x00008122, 4096,   16384, 1024, BINARY,   0x10000300 },
///added for LPC82x series
    { "LPC824M201JHI33",        0x00008241, 8192,   32768, 1024, BINARY,   0x10000300 },
    { "LPC822M101JHI33",        0x00008221, 4096,   16384, 1024, BINARY,   0x10000300 },
    { "LPC824M201JDH20",        0x00008242, 8192,   32768, 1024, BINARY,   0x10000300 },
    { "LPC822M101JDH20",        0x00008222, 4096,   16384, 1024, BINARY,   0x10000300 },
 
};

上記コードは以下の構造を取っている.target_table.h に以下のコードがある.

target_table.h

typedef struct  taget_param_st {
    char            *type_name;
    int             id;
    int             ram_size;
    int             flash_size;
    int             sector_size;
    int             write_type;
    unsigned int    ram_start_address;
}

以下の順番にtarget_table.cppにコーディングする.

 {type_name, id, ram_size, flash_size, sector_size, write_type, ram_start_address}

作業の手順例

データはユーザマニュアル(UM)と Data sheet から検索する.以下に例を上げる.

LPC82xxの場合
UM10800 LPC82x User manual http://www.nxp.com/documents/user_manual/UM10800.pdf
LPC82x Product data sheet http://www.nxp.com/documents/data_sheet/LPC82X.pdf

  • type_name:
    • UMから Part identification numbers を検索すると,Table 322. Part identification numbersが現れる.Table 322より Table記載のDeviceを入力.
  • id:
    • UMから Part identification numbers を検索,Table 322. よりHex codingを入力.
  • ram_size:
    • Product data sheet よりOrdering options を検索しTable2より上記Deviceと同じターゲットのRAMサイズを記載(byte)
  • flash_size:
    • Product data sheet よりOrdering options を検索しTable2より上記Deviceと同じターゲットのFlashサイズを記載(byte)
      尚,1KBは1024byteにて計算
  • sector_size:
    • UMから Flash configuration を検索し25.5 General description に「The size of a sector is 1 KB and the size of a page is 64 Byte. One sector contains 16 pages.」と記載があるので,ターゲットのSectorサイズを記載(byte単位).今回の場合は1KBなので1024byte.
    • LPC176xシリーズのセクタサイズは,最初の16セクタが4KB,残りを32KBとしているため一定の値では表せません.これに対応するため特別な値を用意して,プログラム内でその値を検出した際には実際の構成に則した計算を行うようにしています.
  • ram_start_address:
    • UMからUART ISP Write to RAM command もしくは Write to RAM を検索.Example に書いてあるアドレスを記載する.

参考

日本語版だけの(何の役にも立たない)参考情報

Information

何故このプログラムが作られたか.そして何故こんな名前なのか.
こちらを御覧ください →→ イカ醤油ポッポ焼きはイカにして生まれたか(´(ェ)`;

このプログラムを作ってみるきっかけになったツイート.

(´(ェ)`)

Committer:
okano
Date:
Tue Jan 06 11:05:29 2015 +0000
Revision:
47:e7d395119a63
Parent:
44:568799eac6df
progress display (during writing/verifying) option added

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okano 22:bd98a782fba6 1
okano 22:bd98a782fba6 2 #include "mbed.h"
okano 22:bd98a782fba6 3 #include "writing.h"
okano 22:bd98a782fba6 4 #include "command_interface.h"
okano 22:bd98a782fba6 5 #include "uu_coding.h"
okano 22:bd98a782fba6 6 #include "serial_utilities.h"
okano 30:e0d7524661ca 7 #include "isp.h"
okano 47:e7d395119a63 8 #include "_user_settings.h"
okano 22:bd98a782fba6 9
okano 22:bd98a782fba6 10
okano 47:e7d395119a63 11 int write_uuencoded_data( FILE *fp, target_param *tpp, int *total_size_p, int file_size );
okano 47:e7d395119a63 12 int write_binary_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start, int *total_size_p, int file_size );
okano 47:e7d395119a63 13 int get_flash_writing_size( int ram_size, unsigned int ram_start );
okano 47:e7d395119a63 14 void show_progress( int total_size, int file_size );
okano 47:e7d395119a63 15
okano 47:e7d395119a63 16
okano 47:e7d395119a63 17 int write_flash( FILE *fp, target_param *tpp, int *transferred_size_p, int file_size )
okano 22:bd98a782fba6 18 {
okano 22:bd98a782fba6 19 if ( tpp->write_type == BINARY )
okano 47:e7d395119a63 20 return ( write_binary_data( fp, tpp->ram_size, tpp->sector_size, tpp->ram_start_address, transferred_size_p, file_size ) );
okano 22:bd98a782fba6 21 else // UUENCODE
okano 47:e7d395119a63 22 return ( write_uuencoded_data( fp, tpp, transferred_size_p, file_size ) );
okano 22:bd98a782fba6 23 }
okano 22:bd98a782fba6 24
okano 22:bd98a782fba6 25
okano 44:568799eac6df 26
okano 44:568799eac6df 27
okano 44:568799eac6df 28
okano 47:e7d395119a63 29 int write_uuencoded_data( FILE *fp, target_param *tpp, int *total_size_p, int file_size )
okano 22:bd98a782fba6 30 {
okano 22:bd98a782fba6 31 #define BYTES_PER_LINE 45
okano 22:bd98a782fba6 32
okano 22:bd98a782fba6 33 char command_str[ STR_BUFF_SIZE ];
okano 22:bd98a782fba6 34 long checksum = 0;
okano 29:96e28bc1bd99 35 int size;
okano 22:bd98a782fba6 36 int total_size = 0;
okano 44:568799eac6df 37 int sector_number;
okano 22:bd98a782fba6 38
okano 22:bd98a782fba6 39 int flash_writing_size;
okano 22:bd98a782fba6 40 int lines_per_transfer;
okano 22:bd98a782fba6 41 int transfer_size;
okano 22:bd98a782fba6 42
okano 22:bd98a782fba6 43 char *b;
okano 47:e7d395119a63 44
okano 44:568799eac6df 45 int ram_size = tpp->ram_size;
okano 44:568799eac6df 46 unsigned int ram_start = tpp->ram_start_address;
okano 29:96e28bc1bd99 47
okano 22:bd98a782fba6 48 initialize_uue_table();
okano 22:bd98a782fba6 49
okano 22:bd98a782fba6 50 flash_writing_size = get_flash_writing_size( ram_size, ram_start );
okano 22:bd98a782fba6 51 lines_per_transfer = ((flash_writing_size / BYTES_PER_LINE) + 1);
okano 22:bd98a782fba6 52 transfer_size = (((flash_writing_size + 11) / 12) * 12);
okano 22:bd98a782fba6 53
okano 22:bd98a782fba6 54 // char b[ transfer_size ]; // this can be done in mbed-compiler. but I should do it in common way
okano 22:bd98a782fba6 55
okano 22:bd98a782fba6 56 if ( NULL == (b = (char *)malloc( transfer_size * sizeof( char ) )) )
okano 28:689c3880e0e4 57 return( ERROR_AT_MALLOC_FOR_WRITE_BUFF );
okano 22:bd98a782fba6 58
okano 22:bd98a782fba6 59 for ( int i = flash_writing_size; i < transfer_size; i++ )
okano 22:bd98a782fba6 60 b[ i ] = 0; // this is not neccesary but just stuffing stuffing bytes
okano 22:bd98a782fba6 61
okano 22:bd98a782fba6 62 while ( size = fread( b, sizeof( char ), flash_writing_size, fp ) ) {
okano 22:bd98a782fba6 63
okano 22:bd98a782fba6 64 if ( !total_size ) {
okano 22:bd98a782fba6 65 // overwriting 4 bytes data for address=0x1C
okano 22:bd98a782fba6 66 // there is a slot for checksum that is checked in (target's) boot process
okano 22:bd98a782fba6 67 add_isp_checksum( b );
okano 22:bd98a782fba6 68 }
okano 22:bd98a782fba6 69
okano 22:bd98a782fba6 70 sprintf( command_str, "W %ld %ld\r\n", ram_start, transfer_size );
okano 35:0b434ef4af49 71 if ( try_and_check( command_str, "0" ) )
okano 27:2b5c1eb39bb5 72 return ( ERROR_AT_WRITE_COMMAND );
okano 22:bd98a782fba6 73
okano 22:bd98a782fba6 74 for ( int i = 0; i < lines_per_transfer; i++ ) {
okano 22:bd98a782fba6 75
okano 22:bd98a782fba6 76 checksum += bin2uue( b + (i * BYTES_PER_LINE), command_str, i == (lines_per_transfer - 1) ? (transfer_size % BYTES_PER_LINE) : BYTES_PER_LINE );
okano 22:bd98a782fba6 77
okano 22:bd98a782fba6 78 // printf( " data -- %02d %s\r", i, command_str );
okano 22:bd98a782fba6 79
okano 22:bd98a782fba6 80 put_string( command_str );
okano 22:bd98a782fba6 81
okano 22:bd98a782fba6 82 if ( !((i + 1) % 20) ) {
okano 28:689c3880e0e4 83 if ( send_RAM_transfer_checksum( checksum ) )
okano 28:689c3880e0e4 84 return ( ERROR_AT_SENDING_CHECKSUM );
okano 28:689c3880e0e4 85
okano 22:bd98a782fba6 86 checksum = 0;
okano 22:bd98a782fba6 87 }
okano 22:bd98a782fba6 88 }
okano 22:bd98a782fba6 89
okano 28:689c3880e0e4 90 if ( send_RAM_transfer_checksum( checksum ) )
okano 28:689c3880e0e4 91 return ( ERROR_AT_SENDING_CHECKSUM );
okano 28:689c3880e0e4 92
okano 22:bd98a782fba6 93 checksum = 0;
okano 22:bd98a782fba6 94
okano 44:568799eac6df 95 // sprintf( command_str, "P %d %d\r\n", total_size / sector_size, total_size / sector_size );
okano 44:568799eac6df 96
okano 44:568799eac6df 97 sector_number = find_sector( total_size, tpp );
okano 44:568799eac6df 98 sprintf( command_str, "P %d %d\r\n", sector_number, sector_number );
okano 47:e7d395119a63 99
okano 35:0b434ef4af49 100 if ( try_and_check( command_str, "0" ) )
okano 28:689c3880e0e4 101 return ( ERROR_AT_PREPARE_COMMAND );
okano 22:bd98a782fba6 102
okano 22:bd98a782fba6 103 sprintf( command_str, "C %d %d %d\r\n", total_size, ram_start, flash_writing_size );
okano 35:0b434ef4af49 104 if ( try_and_check( command_str, "0" ) )
okano 27:2b5c1eb39bb5 105 return ( ERROR_AT_COPY_COMMAND );
okano 22:bd98a782fba6 106
okano 22:bd98a782fba6 107 total_size += size;
okano 47:e7d395119a63 108
okano 47:e7d395119a63 109 #ifdef ENABLE_PROGRESS_DISPLAY
okano 47:e7d395119a63 110 show_progress( total_size, file_size );
okano 47:e7d395119a63 111 #endif
okano 22:bd98a782fba6 112 }
okano 22:bd98a782fba6 113
okano 22:bd98a782fba6 114 free( b );
okano 29:96e28bc1bd99 115 *total_size_p = total_size;
okano 22:bd98a782fba6 116
okano 27:2b5c1eb39bb5 117 return ( NO_ERROR );
okano 22:bd98a782fba6 118 }
okano 22:bd98a782fba6 119
okano 22:bd98a782fba6 120
okano 47:e7d395119a63 121 int write_binary_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start, int *total_size_p, int file_size )
okano 22:bd98a782fba6 122 {
okano 22:bd98a782fba6 123 char command_str[ STR_BUFF_SIZE ];
okano 29:96e28bc1bd99 124 int total_size = 0;
okano 22:bd98a782fba6 125 int size;
okano 22:bd98a782fba6 126 int flash_writing_size;
okano 22:bd98a782fba6 127 char *b;
okano 22:bd98a782fba6 128
okano 22:bd98a782fba6 129 flash_writing_size = 256;
okano 22:bd98a782fba6 130
okano 22:bd98a782fba6 131 if ( NULL == (b = (char *)malloc( flash_writing_size * sizeof( char ) )) )
okano 28:689c3880e0e4 132 return( ERROR_AT_MALLOC_FOR_WRITE_BUFF );
okano 22:bd98a782fba6 133
okano 22:bd98a782fba6 134 while ( size = fread( b, sizeof( char ), flash_writing_size, fp ) ) {
okano 22:bd98a782fba6 135
okano 22:bd98a782fba6 136 if ( !total_size ) {
okano 22:bd98a782fba6 137 // overwriting 4 bytes data for address=0x1C
okano 22:bd98a782fba6 138 // there is a slot for checksum that is checked in (target's) boot process
okano 22:bd98a782fba6 139 add_isp_checksum( b );
okano 22:bd98a782fba6 140 }
okano 22:bd98a782fba6 141
okano 22:bd98a782fba6 142 sprintf( command_str, "W %ld %ld\r\n", ram_start, flash_writing_size );
okano 35:0b434ef4af49 143 if ( try_and_check( command_str, "0" ) )
okano 27:2b5c1eb39bb5 144 return ( ERROR_AT_WRITE_COMMAND );
okano 22:bd98a782fba6 145
okano 22:bd98a782fba6 146 put_binary( b, flash_writing_size );
okano 22:bd98a782fba6 147 put_string( "\r\n" );
okano 22:bd98a782fba6 148
okano 22:bd98a782fba6 149 sprintf( command_str, "P %d %d\r\n", total_size / sector_size, total_size / sector_size );
okano 35:0b434ef4af49 150 if ( try_and_check( command_str, "0" ) )
okano 28:689c3880e0e4 151 return ( ERROR_AT_PREPARE_COMMAND );
okano 22:bd98a782fba6 152
okano 22:bd98a782fba6 153 sprintf( command_str, "C %d %d %d\r\n", total_size, ram_start, flash_writing_size );
okano 35:0b434ef4af49 154 if ( try_and_check( command_str, "0" ) )
okano 27:2b5c1eb39bb5 155 return ( ERROR_AT_COPY_COMMAND );
okano 22:bd98a782fba6 156
okano 22:bd98a782fba6 157 total_size += size;
okano 22:bd98a782fba6 158 //printf( " total %d bytes transferred\r", total_size );
okano 22:bd98a782fba6 159
okano 47:e7d395119a63 160 #ifdef ENABLE_PROGRESS_DISPLAY
okano 47:e7d395119a63 161 show_progress( total_size, file_size );
okano 47:e7d395119a63 162 #endif
okano 22:bd98a782fba6 163 }
okano 22:bd98a782fba6 164
okano 22:bd98a782fba6 165 free( b );
okano 29:96e28bc1bd99 166 *total_size_p = total_size;
okano 22:bd98a782fba6 167
okano 27:2b5c1eb39bb5 168 return ( NO_ERROR );
okano 22:bd98a782fba6 169 }
okano 22:bd98a782fba6 170
okano 22:bd98a782fba6 171
okano 22:bd98a782fba6 172 void add_isp_checksum( char *b )
okano 22:bd98a782fba6 173 {
okano 22:bd98a782fba6 174 // see http://www.lpcware.com/content/nxpfile/lpc177x8x-checksum-insertion-program
okano 22:bd98a782fba6 175
okano 22:bd98a782fba6 176 unsigned int *p;
okano 22:bd98a782fba6 177 unsigned int cksum = 0;
okano 22:bd98a782fba6 178
okano 22:bd98a782fba6 179 p = (unsigned int *)b;
okano 22:bd98a782fba6 180
okano 22:bd98a782fba6 181 for ( int i = 0; i < 7; i++ ) {
okano 22:bd98a782fba6 182 cksum += *p++;
okano 22:bd98a782fba6 183 }
okano 22:bd98a782fba6 184
okano 22:bd98a782fba6 185 printf( " -- value at checksum slot : 0x%08X\r\n", *p );
okano 22:bd98a782fba6 186
okano 22:bd98a782fba6 187 *p = 0xFFFFFFFF - cksum + 1;
okano 22:bd98a782fba6 188 printf( " -- calculated checksum : 0x%08X\r\n", *p );
okano 22:bd98a782fba6 189
okano 26:a63e73885b21 190 printf( " new checksum will be used programing flash\r\n" );
okano 22:bd98a782fba6 191 }
okano 22:bd98a782fba6 192
okano 22:bd98a782fba6 193
okano 22:bd98a782fba6 194 int get_flash_writing_size( int ram_size, unsigned int ram_start )
okano 22:bd98a782fba6 195 {
okano 22:bd98a782fba6 196 int flash_writing_size[] = {
okano 22:bd98a782fba6 197 4096,
okano 22:bd98a782fba6 198 1024,
okano 22:bd98a782fba6 199 512,
okano 22:bd98a782fba6 200 256
okano 22:bd98a782fba6 201 };
okano 22:bd98a782fba6 202 int available_size;
okano 22:bd98a782fba6 203 int i;
okano 22:bd98a782fba6 204
okano 22:bd98a782fba6 205 available_size = ram_size - (ram_start & 0xFFFF);
okano 22:bd98a782fba6 206
okano 22:bd98a782fba6 207 for ( i = 0; i < sizeof( flash_writing_size ) / sizeof( int ); i++ ) {
okano 22:bd98a782fba6 208 if ( flash_writing_size[ i ] < available_size )
okano 22:bd98a782fba6 209 break;
okano 22:bd98a782fba6 210 }
okano 22:bd98a782fba6 211
okano 22:bd98a782fba6 212 return ( flash_writing_size[ i ] );
okano 28:689c3880e0e4 213 }
okano 28:689c3880e0e4 214
okano 28:689c3880e0e4 215
okano 28:689c3880e0e4 216 int post_writing_process( target_param *tpp )
okano 28:689c3880e0e4 217 {
okano 28:689c3880e0e4 218 if ( tpp->write_type == UUENCODE )
okano 35:0b434ef4af49 219 return ( try_and_check( "G 0 T\r\n", "0" ) );
okano 28:689c3880e0e4 220 else
okano 28:689c3880e0e4 221 return ( 0 );
okano 28:689c3880e0e4 222 }