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:
Thu Sep 12 19:51:33 2013 +0000
Revision:
19:7a7381e78025
Parent:
18:b401da200216
Child:
20:98d7b5878e3e
verification function is available for "BINARY transfer" device (LPC810)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okano 11:8dfc3217d1ca 1 /**
okano 11:8dfc3217d1ca 2 * Sample of ISP operation for NXP MCUs
okano 11:8dfc3217d1ca 3 *
okano 14:a7b9f74fb856 4 * @author Tedd OKANO
okano 19:7a7381e78025 5 * @version 0.8
okano 18:b401da200216 6 * @date Sep-2013
okano 14:a7b9f74fb856 7 *
okano 14:a7b9f74fb856 8 * This program programs MCU flash memory through UART. It uses
okano 14:a7b9f74fb856 9 * "In-System Programming (ISP)" interface in target MCU (NXP LPC micro-
okano 14:a7b9f74fb856 10 * controllers).
okano 14:a7b9f74fb856 11 *
okano 14:a7b9f74fb856 12 * The ISP is done by PC and serial cable normally. The ISP protocol is
okano 14:a7b9f74fb856 13 * executed software on a PC. The software reads a data file and transfers
okano 14:a7b9f74fb856 14 * the data with the ISP protocol.
okano 14:a7b9f74fb856 15 * This program does same process of that. The mbed perform the function like
okano 14:a7b9f74fb856 16 * "FlashMagic" and "lpc21isp".
okano 14:a7b9f74fb856 17 * (This program not just copies the binary but also insert 4 byte checksum at
okano 14:a7b9f74fb856 18 * address 0x1C.)
okano 14:a7b9f74fb856 19 *
okano 14:a7b9f74fb856 20 * This program currently supports LPC1114(LPC1114FN28/102 - DIP28-ARM) and
okano 14:a7b9f74fb856 21 * LPC810(LPC810M021FN8 - DIP8-ARM).
okano 11:8dfc3217d1ca 22 */
okano 11:8dfc3217d1ca 23
okano 5:ff30f5b58617 24 #include "mbed.h"
okano 5:ff30f5b58617 25 #include "target_table.h"
okano 0:6baefda2e511 26
okano 2:8d75eb0ecd20 27 BusOut leds( LED4, LED3, LED2, LED1 );
okano 2:8d75eb0ecd20 28 DigitalOut reset_pin( p26 );
okano 2:8d75eb0ecd20 29 DigitalOut isp_pin( p25 );
okano 16:cac2348cfcfb 30 Serial pc ( USBTX,USBRX );
okano 2:8d75eb0ecd20 31 LocalFileSystem local( "local" );
okano 16:cac2348cfcfb 32 Ticker success;
okano 0:6baefda2e511 33
okano 19:7a7381e78025 34
okano 19:7a7381e78025 35 #if 0
okano 19:7a7381e78025 36 Serial target( p28, p27 );
okano 19:7a7381e78025 37 #else
okano 19:7a7381e78025 38 #define MODSERIAL_DEFAULT_RX_BUFFER_SIZE 512
okano 19:7a7381e78025 39 #define MODSERIAL_DEFAULT_TX_BUFFER_SIZE 512
okano 19:7a7381e78025 40 #include "MODSERIAL.h"
okano 19:7a7381e78025 41 MODSERIAL target( p28, p27 ); //
okano 19:7a7381e78025 42 #endif
okano 19:7a7381e78025 43
okano 19:7a7381e78025 44
okano 19:7a7381e78025 45
okano 12:5a33b5d39792 46 #define ENTER_TO_ISP_MODE 0
okano 12:5a33b5d39792 47 #define NO_ISP_MODE 1
okano 12:5a33b5d39792 48 #define STR_BUFF_SIZE 64
okano 12:5a33b5d39792 49
okano 1:54e619428ae6 50 #define SOURCE_FILE "/local/bin"
okano 18:b401da200216 51
okano 18:b401da200216 52 // "ISP_BAUD_RATE" is baud rate for ISP operation
okano 18:b401da200216 53
okano 16:cac2348cfcfb 54 #define ISP_BAUD_RATE 115200
okano 16:cac2348cfcfb 55 //#define ISP_BAUD_RATE 57600
okano 16:cac2348cfcfb 56 //#define ISP_BAUD_RATE 9600
okano 16:cac2348cfcfb 57
okano 18:b401da200216 58 // "TARGET_OPERATION_BAUD_RATE" is baud rate for USB-serial bridge operation after
okano 18:b401da200216 59 // ISP completion.
okano 18:b401da200216 60 // if the target application uses serial(UART) and you use the bridge feature,
okano 18:b401da200216 61 // please set this value correctly.
okano 18:b401da200216 62
okano 16:cac2348cfcfb 63 #define TARGET_OPERATION_BAUD_RATE 9600
okano 4:55f1977bd11a 64
okano 8:b220fadbb3d8 65 int error_state = 0;
okano 7:815366f003ee 66
okano 7:815366f003ee 67 int file_size( FILE *fp );
okano 7:815366f003ee 68 void reset_target( int isp_pin_state );
okano 7:815366f003ee 69 int try_and_check( char *command, char *expected_return_str, int mode );
okano 7:815366f003ee 70 int try_and_check2( char *command, char *expected_return_str, int mode );
okano 7:815366f003ee 71 void print_command( char *command );
okano 7:815366f003ee 72 void print_result( int r );
okano 7:815366f003ee 73 char read_byte( void );
okano 7:815366f003ee 74 void erase_sectors( int last_sector );
okano 12:5a33b5d39792 75 int write_uuencoded_data( FILE *fp, int ram_size, int sector_size, unsigned int );
okano 12:5a33b5d39792 76 int write_binary_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start );
okano 19:7a7381e78025 77 int verify_binary_data( FILE *fp );
okano 7:815366f003ee 78 void initialize_uue_table( void );
okano 11:8dfc3217d1ca 79 long bin2uue( char *bin, char *str, int size );
okano 12:5a33b5d39792 80 int get_flash_writing_size( int ram_size, unsigned int ram_start );
okano 7:815366f003ee 81 void add_isp_checksum( char *b );
okano 7:815366f003ee 82 void send_RAM_transfer_checksum( int checksum );
okano 7:815366f003ee 83 void put_string( char *s );
okano 12:5a33b5d39792 84 void put_binary( char *b, int size );
okano 7:815366f003ee 85 void get_string( char *s );
okano 19:7a7381e78025 86 int get_binary( char *b, int length );
okano 16:cac2348cfcfb 87 void success_indicator();
okano 7:815366f003ee 88
okano 19:7a7381e78025 89
okano 12:5a33b5d39792 90 #pragma diag_suppress 1293 // surpressing a warning message of "assignment in condition" ;)
okano 12:5a33b5d39792 91
okano 7:815366f003ee 92
okano 7:815366f003ee 93 int main()
okano 7:815366f003ee 94 {
okano 7:815366f003ee 95 FILE *fp;
okano 7:815366f003ee 96 char str_buf0[ STR_BUFF_SIZE ];
okano 7:815366f003ee 97 char str_buf1[ STR_BUFF_SIZE ];
okano 7:815366f003ee 98 int data_size;
okano 7:815366f003ee 99 int last_sector;
okano 7:815366f003ee 100 target_param *tpp;
okano 8:b220fadbb3d8 101
okano 7:815366f003ee 102 printf( "\r\n\r\n\r\nmbed ISP program : programming LPC device from mbed\r\n" );
okano 7:815366f003ee 103
okano 16:cac2348cfcfb 104 target.baud( ISP_BAUD_RATE );
okano 8:b220fadbb3d8 105
okano 7:815366f003ee 106 reset_target( ENTER_TO_ISP_MODE );
okano 8:b220fadbb3d8 107
okano 7:815366f003ee 108 try_and_check( "?", "Synchronized", 0 );
okano 8:b220fadbb3d8 109
okano 7:815366f003ee 110 try_and_check2( "Synchronized\r\n", "OK", 0 );
okano 7:815366f003ee 111 try_and_check2( "12000\r\n", "OK", 0 );
okano 7:815366f003ee 112 try_and_check2( "U 23130\r\n", "0", 0 );
okano 7:815366f003ee 113 try_and_check2( "A 0\r\n", "0", 0 );
okano 8:b220fadbb3d8 114
okano 7:815366f003ee 115 try_and_check( "K\r\n", "0", 0 );
okano 7:815366f003ee 116 get_string( str_buf0 );
okano 7:815366f003ee 117 get_string( str_buf1 );
okano 8:b220fadbb3d8 118
okano 7:815366f003ee 119 printf( " result of \"K\" = %s %s\r\n", str_buf0, str_buf1 );
okano 8:b220fadbb3d8 120
okano 7:815366f003ee 121 try_and_check( "J\r\n", "0", 0 );
okano 7:815366f003ee 122 get_string( str_buf0 );
okano 8:b220fadbb3d8 123
okano 7:815366f003ee 124 printf( " result of \"J\" = %s\r\n", str_buf0 );
okano 8:b220fadbb3d8 125
okano 7:815366f003ee 126 tpp = find_target_param( str_buf0 );
okano 8:b220fadbb3d8 127 printf( " target device found : type = \"%s\"\r\n", tpp->type_name );
okano 8:b220fadbb3d8 128 printf( " ID = 0x%08X\r\n", tpp->id );
okano 8:b220fadbb3d8 129 printf( " RAM size = %10d bytes\r\n", tpp->ram_size );
okano 8:b220fadbb3d8 130 printf( " flash size = %10d bytes\r\n", tpp->flash_size );
okano 8:b220fadbb3d8 131
okano 12:5a33b5d39792 132 printf( " opening file: \"%s\"\r\n", SOURCE_FILE );
okano 12:5a33b5d39792 133
okano 12:5a33b5d39792 134 if ( NULL == (fp = fopen( SOURCE_FILE, "rb" )) ) {
okano 12:5a33b5d39792 135 error( "couldn't open source file" );
okano 12:5a33b5d39792 136 return ( 1 );
okano 12:5a33b5d39792 137 }
okano 12:5a33b5d39792 138
okano 12:5a33b5d39792 139 data_size = file_size( fp );
okano 12:5a33b5d39792 140 last_sector = data_size / tpp->sector_size;
okano 12:5a33b5d39792 141
okano 12:5a33b5d39792 142 printf( " data size = %d bytes, it takes %d secotrs in flash area\r\n", data_size, last_sector + 1 );
okano 12:5a33b5d39792 143 printf( " resetting target\r\n" );
okano 12:5a33b5d39792 144
okano 7:815366f003ee 145 erase_sectors( last_sector );
okano 12:5a33b5d39792 146
okano 12:5a33b5d39792 147 if ( tpp->write_type == BINARY )
okano 12:5a33b5d39792 148 write_binary_data( fp, tpp->ram_size, tpp->sector_size, tpp->ram_start_address );
okano 12:5a33b5d39792 149 else // UUENCODE
okano 12:5a33b5d39792 150 write_uuencoded_data( fp, tpp->ram_size, tpp->sector_size, tpp->ram_start_address );
okano 12:5a33b5d39792 151
okano 7:815366f003ee 152 fclose( fp );
okano 8:b220fadbb3d8 153
okano 8:b220fadbb3d8 154 printf( "\r\n %s\r\n\r\n",
okano 8:b220fadbb3d8 155 error_state ?
okano 8:b220fadbb3d8 156 "** The data could not be written :(" :
okano 8:b220fadbb3d8 157 "** The data has been written successflly :)"
okano 8:b220fadbb3d8 158 );
okano 19:7a7381e78025 159
okano 19:7a7381e78025 160 if ( error_state )
okano 19:7a7381e78025 161 error( " ** ISP failed\r\n" );
okano 8:b220fadbb3d8 162
okano 16:cac2348cfcfb 163 #define AUTO_PROGRAM_START
okano 14:a7b9f74fb856 164 #ifdef AUTO_PROGRAM_START
okano 16:cac2348cfcfb 165 target.baud( TARGET_OPERATION_BAUD_RATE );
okano 16:cac2348cfcfb 166
okano 14:a7b9f74fb856 167 reset_target( NO_ISP_MODE );
okano 16:cac2348cfcfb 168 printf( " ** The program in flash has been started!!\r\n" );
okano 14:a7b9f74fb856 169 #endif
okano 14:a7b9f74fb856 170
okano 16:cac2348cfcfb 171 printf( " (now the mbed is working in \"serial through mode\")\r\n\r\n" );
okano 16:cac2348cfcfb 172
okano 16:cac2348cfcfb 173 success.attach( &success_indicator, 0.1 );
okano 16:cac2348cfcfb 174
okano 16:cac2348cfcfb 175 while (1) {
okano 8:b220fadbb3d8 176
okano 16:cac2348cfcfb 177 if ( pc.readable() ) {
okano 16:cac2348cfcfb 178 target.putc( pc.getc() );
okano 16:cac2348cfcfb 179 }
okano 16:cac2348cfcfb 180
okano 16:cac2348cfcfb 181 if ( target.readable() ) {
okano 16:cac2348cfcfb 182 pc.putc( target.getc() );
okano 16:cac2348cfcfb 183 }
okano 16:cac2348cfcfb 184
okano 7:815366f003ee 185 }
okano 7:815366f003ee 186 }
okano 7:815366f003ee 187
okano 7:815366f003ee 188
okano 7:815366f003ee 189 int file_size( FILE *fp )
okano 7:815366f003ee 190 {
okano 7:815366f003ee 191 int size;
okano 8:b220fadbb3d8 192
okano 7:815366f003ee 193 fseek( fp, 0, SEEK_END ); // seek to end of file
okano 7:815366f003ee 194 size = ftell( fp ); // get current file pointer
okano 7:815366f003ee 195 fseek( fp, 0, SEEK_SET ); // seek back to beginning of file
okano 8:b220fadbb3d8 196
okano 7:815366f003ee 197 return size;
okano 7:815366f003ee 198 }
okano 7:815366f003ee 199
okano 7:815366f003ee 200
okano 7:815366f003ee 201 void reset_target( int isp_pin_state )
okano 7:815366f003ee 202 {
okano 7:815366f003ee 203 reset_pin = 1;
okano 13:60995bf8b2c7 204 isp_pin = isp_pin_state;
okano 7:815366f003ee 205 wait_ms( 100 );
okano 13:60995bf8b2c7 206
okano 7:815366f003ee 207 reset_pin = 0;
okano 7:815366f003ee 208 wait_ms( 100 );
okano 13:60995bf8b2c7 209
okano 7:815366f003ee 210 reset_pin = 1;
okano 7:815366f003ee 211 wait_ms( 100 );
okano 7:815366f003ee 212 }
okano 7:815366f003ee 213
okano 7:815366f003ee 214
okano 7:815366f003ee 215 int try_and_check( char *command, char *expected_return_str, int mode )
okano 7:815366f003ee 216 {
okano 7:815366f003ee 217 char rtn_str[ STR_BUFF_SIZE ];
okano 8:b220fadbb3d8 218 int result = 1;
okano 8:b220fadbb3d8 219
okano 7:815366f003ee 220 print_command( command );
okano 7:815366f003ee 221 put_string( command );
okano 8:b220fadbb3d8 222
okano 7:815366f003ee 223 get_string( rtn_str );
okano 7:815366f003ee 224 print_result( result = strcmp( expected_return_str, rtn_str ) );
okano 8:b220fadbb3d8 225
okano 8:b220fadbb3d8 226 if ( result && !mode )
okano 8:b220fadbb3d8 227 error( "command failed\r\n" );
okano 8:b220fadbb3d8 228
okano 8:b220fadbb3d8 229 error_state |= result;
okano 8:b220fadbb3d8 230
okano 7:815366f003ee 231 return ( result );
okano 7:815366f003ee 232 }
okano 7:815366f003ee 233
okano 7:815366f003ee 234
okano 7:815366f003ee 235 int try_and_check2( char *command, char *expected_return_str, int mode )
okano 7:815366f003ee 236 {
okano 7:815366f003ee 237 char rtn_str[ STR_BUFF_SIZE ];
okano 8:b220fadbb3d8 238 int result = 1;
okano 8:b220fadbb3d8 239
okano 7:815366f003ee 240 print_command( command );
okano 7:815366f003ee 241 put_string( command );
okano 8:b220fadbb3d8 242
okano 7:815366f003ee 243 get_string( rtn_str ); // just readout echoback
okano 7:815366f003ee 244 get_string( rtn_str );
okano 7:815366f003ee 245 print_result( result = strcmp( expected_return_str, rtn_str ) );
okano 8:b220fadbb3d8 246
okano 8:b220fadbb3d8 247 if ( result && !mode )
okano 8:b220fadbb3d8 248 error( "command failed\r\n" );
okano 8:b220fadbb3d8 249
okano 8:b220fadbb3d8 250 error_state |= result;
okano 8:b220fadbb3d8 251
okano 7:815366f003ee 252 return ( result );
okano 7:815366f003ee 253 }
okano 7:815366f003ee 254
okano 7:815366f003ee 255
okano 7:815366f003ee 256 void print_command( char *command )
okano 7:815366f003ee 257 {
okano 7:815366f003ee 258 char s[ STR_BUFF_SIZE ];
okano 7:815366f003ee 259 char *pos;
okano 8:b220fadbb3d8 260
okano 7:815366f003ee 261 strcpy( s, command );
okano 8:b220fadbb3d8 262
okano 7:815366f003ee 263 if ( pos = strchr( s, '\r' ) )
okano 7:815366f003ee 264 *pos = '\0';
okano 8:b220fadbb3d8 265
okano 7:815366f003ee 266 if ( pos = strchr( s, '\n' ) )
okano 7:815366f003ee 267 *pos = '\0';
okano 8:b220fadbb3d8 268
okano 7:815366f003ee 269 printf( " command-\"%s\" : ", s );
okano 7:815366f003ee 270 }
okano 7:815366f003ee 271
okano 7:815366f003ee 272
okano 7:815366f003ee 273 void print_result( int r )
okano 7:815366f003ee 274 {
okano 7:815366f003ee 275 printf( "%s\r\n", r ? "Fail" : "Pass" );
okano 7:815366f003ee 276 }
okano 7:815366f003ee 277
okano 7:815366f003ee 278
okano 7:815366f003ee 279 char read_byte( void )
okano 7:815366f003ee 280 {
okano 7:815366f003ee 281 while ( !target.readable() )
okano 7:815366f003ee 282 ;
okano 8:b220fadbb3d8 283
okano 7:815366f003ee 284 return ( target.getc() );
okano 7:815366f003ee 285 }
okano 7:815366f003ee 286
okano 7:815366f003ee 287
okano 7:815366f003ee 288 void erase_sectors( int last_sector )
okano 7:815366f003ee 289 {
okano 7:815366f003ee 290 char command_str[ STR_BUFF_SIZE ];
okano 8:b220fadbb3d8 291
okano 7:815366f003ee 292 sprintf( command_str, "P 0 %d\r\n", last_sector );
okano 7:815366f003ee 293 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 294
okano 7:815366f003ee 295 *(command_str) = 'E';
okano 7:815366f003ee 296 try_and_check( command_str, "0", 0 );
okano 7:815366f003ee 297 }
okano 7:815366f003ee 298
okano 12:5a33b5d39792 299 #define BYTES_PER_LINE 45
okano 12:5a33b5d39792 300 char uue_table[ 64 ];
okano 7:815366f003ee 301
okano 12:5a33b5d39792 302 int write_uuencoded_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start )
okano 7:815366f003ee 303 {
okano 7:815366f003ee 304 char command_str[ STR_BUFF_SIZE ];
okano 7:815366f003ee 305 long checksum = 0;
okano 7:815366f003ee 306 int total_size = 0;
okano 7:815366f003ee 307 int size;
okano 8:b220fadbb3d8 308
okano 7:815366f003ee 309 int flash_writing_size;
okano 7:815366f003ee 310 int lines_per_transfer;
okano 7:815366f003ee 311 int transfer_size;
okano 8:b220fadbb3d8 312
okano 12:5a33b5d39792 313 char *b;
okano 12:5a33b5d39792 314
okano 7:815366f003ee 315 initialize_uue_table();
okano 8:b220fadbb3d8 316
okano 12:5a33b5d39792 317 flash_writing_size = get_flash_writing_size( ram_size, ram_start );
okano 11:8dfc3217d1ca 318 lines_per_transfer = ((flash_writing_size / BYTES_PER_LINE) + 1);
okano 11:8dfc3217d1ca 319 transfer_size = (((flash_writing_size + 11) / 12) * 12);
okano 8:b220fadbb3d8 320
okano 7:815366f003ee 321 // char b[ transfer_size ]; // this can be done in mbed-compiler. but I should do it in common way
okano 8:b220fadbb3d8 322
okano 7:815366f003ee 323 if ( NULL == (b = (char *)malloc( transfer_size * sizeof( char ) )) )
okano 7:815366f003ee 324 error( "malloc error happened\r\n" );
okano 8:b220fadbb3d8 325
okano 7:815366f003ee 326 for ( int i = flash_writing_size; i < transfer_size; i++ )
okano 7:815366f003ee 327 b[ i ] = 0; // this is not neccesary but just stuffing stuffing bytes
okano 8:b220fadbb3d8 328
okano 7:815366f003ee 329 while ( size = fread( b, sizeof( char ), flash_writing_size, fp ) ) {
okano 8:b220fadbb3d8 330
okano 7:815366f003ee 331 if ( !total_size ) {
okano 7:815366f003ee 332 // overwriting 4 bytes data for address=0x1C
okano 7:815366f003ee 333 // there is a slot for checksum that is checked in (target's) boot process
okano 7:815366f003ee 334 add_isp_checksum( b );
okano 7:815366f003ee 335 }
okano 8:b220fadbb3d8 336
okano 12:5a33b5d39792 337 sprintf( command_str, "W %ld %ld\r\n", ram_start, transfer_size );
okano 7:815366f003ee 338 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 339
okano 7:815366f003ee 340 for ( int i = 0; i < lines_per_transfer; i++ ) {
okano 12:5a33b5d39792 341
okano 11:8dfc3217d1ca 342 checksum += bin2uue( b + (i * BYTES_PER_LINE), command_str, i == (lines_per_transfer - 1) ? (transfer_size % BYTES_PER_LINE) : BYTES_PER_LINE );
okano 8:b220fadbb3d8 343
okano 13:60995bf8b2c7 344 // printf( " data -- %02d %s\r", i, command_str );
okano 8:b220fadbb3d8 345
okano 7:815366f003ee 346 put_string( command_str );
okano 8:b220fadbb3d8 347
okano 7:815366f003ee 348 if ( !((i + 1) % 20) ) {
okano 7:815366f003ee 349 send_RAM_transfer_checksum( checksum );
okano 7:815366f003ee 350 checksum = 0;
okano 7:815366f003ee 351 }
okano 7:815366f003ee 352 }
okano 8:b220fadbb3d8 353
okano 7:815366f003ee 354 send_RAM_transfer_checksum( checksum );
okano 7:815366f003ee 355 checksum = 0;
okano 8:b220fadbb3d8 356
okano 12:5a33b5d39792 357 sprintf( command_str, "P %d %d\r\n", total_size / sector_size, total_size / sector_size );
okano 7:815366f003ee 358 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 359
okano 12:5a33b5d39792 360 sprintf( command_str, "C %d %d %d\r\n", total_size, ram_start, flash_writing_size );
okano 7:815366f003ee 361 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 362
okano 7:815366f003ee 363 total_size += size;
okano 7:815366f003ee 364 }
okano 8:b220fadbb3d8 365
okano 7:815366f003ee 366 try_and_check( "G 0 T\r\n", "0", 0 );
okano 7:815366f003ee 367 free( b );
okano 8:b220fadbb3d8 368
okano 12:5a33b5d39792 369 return ( total_size );
okano 7:815366f003ee 370 }
okano 7:815366f003ee 371
okano 7:815366f003ee 372
okano 12:5a33b5d39792 373 int write_binary_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start )
okano 12:5a33b5d39792 374 {
okano 12:5a33b5d39792 375 char command_str[ STR_BUFF_SIZE ];
okano 12:5a33b5d39792 376 int total_size = 0;
okano 12:5a33b5d39792 377 int size;
okano 12:5a33b5d39792 378 int flash_writing_size;
okano 12:5a33b5d39792 379 char *b;
okano 12:5a33b5d39792 380
okano 12:5a33b5d39792 381 flash_writing_size = 256;
okano 12:5a33b5d39792 382
okano 12:5a33b5d39792 383 if ( NULL == (b = (char *)malloc( flash_writing_size * sizeof( char ) )) )
okano 12:5a33b5d39792 384 error( "malloc error happened\r\n" );
okano 12:5a33b5d39792 385
okano 19:7a7381e78025 386 printf( "\r\n ==== flash writing ====\r\n" );
okano 19:7a7381e78025 387
okano 12:5a33b5d39792 388 while ( size = fread( b, sizeof( char ), flash_writing_size, fp ) ) {
okano 12:5a33b5d39792 389
okano 12:5a33b5d39792 390 if ( !total_size ) {
okano 12:5a33b5d39792 391 // overwriting 4 bytes data for address=0x1C
okano 12:5a33b5d39792 392 // there is a slot for checksum that is checked in (target's) boot process
okano 12:5a33b5d39792 393 add_isp_checksum( b );
okano 12:5a33b5d39792 394 }
okano 12:5a33b5d39792 395
okano 12:5a33b5d39792 396 sprintf( command_str, "W %ld %ld\r\n", ram_start, flash_writing_size );
okano 12:5a33b5d39792 397 try_and_check( command_str, "0", 0 );
okano 12:5a33b5d39792 398
okano 12:5a33b5d39792 399 put_binary( b, flash_writing_size );
okano 12:5a33b5d39792 400 put_string( "\r\n" );
okano 12:5a33b5d39792 401
okano 12:5a33b5d39792 402 sprintf( command_str, "P %d %d\r\n", total_size / sector_size, total_size / sector_size );
okano 12:5a33b5d39792 403 try_and_check( command_str, "0", 0 );
okano 12:5a33b5d39792 404
okano 12:5a33b5d39792 405 sprintf( command_str, "C %d %d %d\r\n", total_size, ram_start, flash_writing_size );
okano 12:5a33b5d39792 406 try_and_check( command_str, "0", 0 );
okano 12:5a33b5d39792 407
okano 12:5a33b5d39792 408 total_size += size;
okano 19:7a7381e78025 409 //printf( " total %d bytes transferred\r", total_size );
okano 12:5a33b5d39792 410
okano 12:5a33b5d39792 411 }
okano 12:5a33b5d39792 412
okano 12:5a33b5d39792 413 free( b );
okano 12:5a33b5d39792 414
okano 19:7a7381e78025 415 verify_binary_data( fp );
okano 19:7a7381e78025 416
okano 12:5a33b5d39792 417 return ( total_size );
okano 12:5a33b5d39792 418 }
okano 12:5a33b5d39792 419
okano 19:7a7381e78025 420
okano 19:7a7381e78025 421 int verify_binary_data( FILE *fp )
okano 19:7a7381e78025 422 {
okano 19:7a7381e78025 423 char command_str[ STR_BUFF_SIZE ];
okano 19:7a7381e78025 424 int read_size = 0;
okano 19:7a7381e78025 425 int size;
okano 19:7a7381e78025 426 int flash_reading_size;
okano 19:7a7381e78025 427 char *bf;
okano 19:7a7381e78025 428 char *br;
okano 19:7a7381e78025 429 int error_flag = 0;
okano 19:7a7381e78025 430 unsigned long checksum = 0;
okano 19:7a7381e78025 431 unsigned long checksum_count = 0;
okano 19:7a7381e78025 432
okano 19:7a7381e78025 433 fseek( fp, 0, SEEK_SET ); // seek back to beginning of file
okano 19:7a7381e78025 434
okano 19:7a7381e78025 435 flash_reading_size = 128;
okano 19:7a7381e78025 436
okano 19:7a7381e78025 437 if ( NULL == (bf = (char *)malloc( flash_reading_size * sizeof( char ) )) )
okano 19:7a7381e78025 438 error( "malloc error happened (in verify process, file data buffer)\r\n" );
okano 19:7a7381e78025 439
okano 19:7a7381e78025 440 if ( NULL == (br = (char *)malloc( flash_reading_size * sizeof( char ) )) )
okano 19:7a7381e78025 441 error( "malloc error happened (in verify process, read data buffer)\r\n" );
okano 19:7a7381e78025 442
okano 19:7a7381e78025 443
okano 19:7a7381e78025 444 printf( "\r\n ==== flash reading and verifying ====\r\n" );
okano 19:7a7381e78025 445
okano 19:7a7381e78025 446 while ( size = fread( bf, sizeof( char ), flash_reading_size, fp ) ) {
okano 19:7a7381e78025 447
okano 19:7a7381e78025 448 if ( read_size < 0x20 ) {
okano 19:7a7381e78025 449 for ( int i = 0; i < flash_reading_size; i += 4 ) {
okano 19:7a7381e78025 450
okano 19:7a7381e78025 451 if ( checksum_count == 7 ) {
okano 19:7a7381e78025 452 checksum = 0xFFFFFFFF - checksum + 1;
okano 19:7a7381e78025 453 *((unsigned int *)(bf + i)) = checksum;
okano 19:7a7381e78025 454 //printf( "\r\n\r\n -- calculated checksum : 0x%08X\r\n", checksum );
okano 19:7a7381e78025 455 } else {
okano 19:7a7381e78025 456 checksum += *((unsigned int *)(bf + i));
okano 19:7a7381e78025 457 }
okano 19:7a7381e78025 458
okano 19:7a7381e78025 459 checksum_count++;
okano 19:7a7381e78025 460 }
okano 19:7a7381e78025 461 }
okano 19:7a7381e78025 462
okano 19:7a7381e78025 463
okano 19:7a7381e78025 464 sprintf( command_str, "R %ld %ld\r\n", read_size, size );
okano 19:7a7381e78025 465 // try_and_check( command_str, "0", MODE_SILENT );
okano 19:7a7381e78025 466 try_and_check( command_str, "0", 0 );
okano 19:7a7381e78025 467
okano 19:7a7381e78025 468 get_binary( br, 1 );
okano 19:7a7381e78025 469 get_binary( br, size );
okano 19:7a7381e78025 470
okano 19:7a7381e78025 471 for ( int i = 0; i < size; i++ ) {
okano 19:7a7381e78025 472 // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) );
okano 19:7a7381e78025 473 if ( (*(bf + i) != *(br + i)) ) {
okano 19:7a7381e78025 474 // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) );
okano 19:7a7381e78025 475 error_flag++;
okano 19:7a7381e78025 476 }
okano 19:7a7381e78025 477 }
okano 19:7a7381e78025 478
okano 19:7a7381e78025 479 if ( error_flag )
okano 19:7a7381e78025 480 break;
okano 19:7a7381e78025 481
okano 19:7a7381e78025 482 read_size += size;
okano 19:7a7381e78025 483
okano 19:7a7381e78025 484 // printf( " total %d bytes read\r\n", read_size );
okano 19:7a7381e78025 485 }
okano 19:7a7381e78025 486
okano 19:7a7381e78025 487 error_state |= error_flag;
okano 19:7a7381e78025 488
okano 19:7a7381e78025 489 printf( " total %d bytes read\r", read_size );
okano 19:7a7381e78025 490 printf( " verification result : \"%s\"\r\n", error_flag ? "Fail" : "Pass" );
okano 19:7a7381e78025 491
okano 19:7a7381e78025 492 free( bf );
okano 19:7a7381e78025 493 free( br );
okano 19:7a7381e78025 494
okano 19:7a7381e78025 495 return ( read_size );
okano 19:7a7381e78025 496 }
okano 19:7a7381e78025 497
okano 19:7a7381e78025 498
okano 7:815366f003ee 499 void initialize_uue_table( void )
okano 7:815366f003ee 500 {
okano 7:815366f003ee 501 int i;
okano 8:b220fadbb3d8 502
okano 7:815366f003ee 503 uue_table[0] = 0x60; // 0x20 is translated to 0x60 !
okano 8:b220fadbb3d8 504
okano 7:815366f003ee 505 for (i = 1; i < 64; i++) {
okano 7:815366f003ee 506 uue_table[i] = (char)(0x20 + i);
okano 7:815366f003ee 507 }
okano 7:815366f003ee 508 }
okano 7:815366f003ee 509
okano 7:815366f003ee 510
okano 11:8dfc3217d1ca 511 long bin2uue( char *bin, char *str, int size )
okano 7:815366f003ee 512 {
okano 7:815366f003ee 513 unsigned long v;
okano 7:815366f003ee 514 long checksum = 0;
okano 7:815366f003ee 515 int strpos = 0;
okano 8:b220fadbb3d8 516
okano 11:8dfc3217d1ca 517 *(str + strpos++) = ' ' + size;
okano 8:b220fadbb3d8 518
okano 11:8dfc3217d1ca 519 for ( int i = 0; i < size; i += 3 ) {
okano 7:815366f003ee 520 checksum += *(bin + i + 0) + *(bin + i + 1) + *(bin + i + 2);
okano 7:815366f003ee 521 v = (*(bin + i + 0) << 16) | (*(bin + i + 1) << 8) | (*(bin + i + 2) << 0);
okano 7:815366f003ee 522 *(str + strpos++) = uue_table[ (v >> 18) & 0x3F ];
okano 7:815366f003ee 523 *(str + strpos++) = uue_table[ (v >> 12) & 0x3F ];
okano 7:815366f003ee 524 *(str + strpos++) = uue_table[ (v >> 6) & 0x3F ];
okano 7:815366f003ee 525 *(str + strpos++) = uue_table[ (v >> 0) & 0x3F ];
okano 7:815366f003ee 526 }
okano 7:815366f003ee 527 *(str + strpos++) = '\n';
okano 7:815366f003ee 528 *(str + strpos++) = '\0';
okano 8:b220fadbb3d8 529
okano 7:815366f003ee 530 return checksum;
okano 7:815366f003ee 531 }
okano 6:0ae6fe8c8512 532
okano 6:0ae6fe8c8512 533
okano 12:5a33b5d39792 534 int get_flash_writing_size( int ram_size, unsigned int ram_start )
okano 6:0ae6fe8c8512 535 {
okano 6:0ae6fe8c8512 536 int flash_writing_size[] = {
okano 6:0ae6fe8c8512 537 4096,
okano 6:0ae6fe8c8512 538 1024,
okano 6:0ae6fe8c8512 539 512,
okano 6:0ae6fe8c8512 540 256
okano 6:0ae6fe8c8512 541 };
okano 6:0ae6fe8c8512 542 int available_size;
okano 6:0ae6fe8c8512 543 int i;
okano 8:b220fadbb3d8 544
okano 12:5a33b5d39792 545 available_size = ram_size - (ram_start & 0xFFFF);
okano 8:b220fadbb3d8 546
okano 6:0ae6fe8c8512 547 for ( i = 0; i < sizeof( flash_writing_size ) / sizeof( int ); i++ ) {
okano 6:0ae6fe8c8512 548 if ( flash_writing_size[ i ] < available_size )
okano 6:0ae6fe8c8512 549 break;
okano 6:0ae6fe8c8512 550 }
okano 8:b220fadbb3d8 551
okano 6:0ae6fe8c8512 552 return ( flash_writing_size[ i ] );
okano 6:0ae6fe8c8512 553 }
okano 4:55f1977bd11a 554
okano 4:55f1977bd11a 555
okano 1:54e619428ae6 556 void add_isp_checksum( char *b )
okano 1:54e619428ae6 557 {
okano 1:54e619428ae6 558 // see http://www.lpcware.com/content/nxpfile/lpc177x8x-checksum-insertion-program
okano 8:b220fadbb3d8 559
okano 1:54e619428ae6 560 unsigned int *p;
okano 1:54e619428ae6 561 unsigned int cksum = 0;
okano 8:b220fadbb3d8 562
okano 1:54e619428ae6 563 p = (unsigned int *)b;
okano 8:b220fadbb3d8 564
okano 1:54e619428ae6 565 for ( int i = 0; i < 7; i++ ) {
okano 1:54e619428ae6 566 cksum += *p++;
okano 1:54e619428ae6 567 }
okano 8:b220fadbb3d8 568
okano 1:54e619428ae6 569 printf( " -- value at checksum slot : 0x%08X\r\n", *p );
okano 8:b220fadbb3d8 570
okano 1:54e619428ae6 571 *p = 0xFFFFFFFF - cksum + 1;
okano 1:54e619428ae6 572 printf( " -- calculated checksum : 0x%08X\r\n", *p );
okano 8:b220fadbb3d8 573
okano 1:54e619428ae6 574 printf( " new checksum will be used to program flash\r\n" );
okano 1:54e619428ae6 575 }
okano 1:54e619428ae6 576
okano 1:54e619428ae6 577
okano 4:55f1977bd11a 578 void send_RAM_transfer_checksum( int checksum )
okano 4:55f1977bd11a 579 {
okano 4:55f1977bd11a 580 char command[ 16 ];
okano 8:b220fadbb3d8 581
okano 4:55f1977bd11a 582 sprintf( command, "%d\n", checksum );
okano 4:55f1977bd11a 583 try_and_check( command, "OK", 0 );
okano 4:55f1977bd11a 584 }
okano 4:55f1977bd11a 585
okano 0:6baefda2e511 586
okano 0:6baefda2e511 587 void put_string( char *s )
okano 0:6baefda2e511 588 {
okano 2:8d75eb0ecd20 589 char c;
okano 2:8d75eb0ecd20 590 static int i = 0;
okano 8:b220fadbb3d8 591
okano 3:3c380e643e74 592 while ( c = *s++ ) {
okano 0:6baefda2e511 593 target.putc( c );
okano 2:8d75eb0ecd20 594 leds = i++ & 0x1;
okano 2:8d75eb0ecd20 595 }
okano 0:6baefda2e511 596 }
okano 0:6baefda2e511 597
okano 7:815366f003ee 598
okano 12:5a33b5d39792 599 void put_binary( char *b, int size )
okano 12:5a33b5d39792 600 {
okano 12:5a33b5d39792 601 for ( int i = 0; i < size; i++ )
okano 12:5a33b5d39792 602 target.putc( *b++ );
okano 12:5a33b5d39792 603 }
okano 12:5a33b5d39792 604
okano 12:5a33b5d39792 605
okano 9:ca4c9a2ac8e1 606 Timeout timeout;
okano 9:ca4c9a2ac8e1 607
okano 9:ca4c9a2ac8e1 608 int timeout_flag = 0;
okano 9:ca4c9a2ac8e1 609
okano 9:ca4c9a2ac8e1 610 void set_flag()
okano 9:ca4c9a2ac8e1 611 {
okano 9:ca4c9a2ac8e1 612 timeout_flag = 1;
okano 9:ca4c9a2ac8e1 613 }
okano 9:ca4c9a2ac8e1 614
okano 9:ca4c9a2ac8e1 615
okano 0:6baefda2e511 616 void get_string( char *s )
okano 0:6baefda2e511 617 {
okano 0:6baefda2e511 618 int i = 0;
okano 0:6baefda2e511 619 char c = 0;
okano 9:ca4c9a2ac8e1 620 timeout_flag = 0;
okano 9:ca4c9a2ac8e1 621
okano 9:ca4c9a2ac8e1 622 timeout.attach( &set_flag, 1 );
okano 8:b220fadbb3d8 623
okano 0:6baefda2e511 624 do {
okano 0:6baefda2e511 625 do {
okano 0:6baefda2e511 626 if ( target.readable() ) {
okano 0:6baefda2e511 627 c = target.getc();
okano 8:b220fadbb3d8 628
okano 0:6baefda2e511 629 if ( ( c == '\n') || (c == '\r') )
okano 0:6baefda2e511 630 break;
okano 8:b220fadbb3d8 631
okano 0:6baefda2e511 632 *s++ = c;
okano 0:6baefda2e511 633 i++;
okano 0:6baefda2e511 634 }
okano 9:ca4c9a2ac8e1 635
okano 9:ca4c9a2ac8e1 636 if ( timeout_flag )
okano 9:ca4c9a2ac8e1 637 return;
okano 0:6baefda2e511 638 } while ( 1 );
okano 0:6baefda2e511 639 } while ( !i );
okano 8:b220fadbb3d8 640
okano 0:6baefda2e511 641 *s = '\0';
okano 0:6baefda2e511 642 }
okano 9:ca4c9a2ac8e1 643
okano 16:cac2348cfcfb 644
okano 19:7a7381e78025 645 int get_binary( char *b, int length )
okano 19:7a7381e78025 646 {
okano 19:7a7381e78025 647 int i;
okano 19:7a7381e78025 648
okano 19:7a7381e78025 649 timeout_flag = 0;
okano 19:7a7381e78025 650 timeout.attach( &set_flag, 1 );
okano 19:7a7381e78025 651
okano 19:7a7381e78025 652 for ( i = 0; i < length; i++ ) {
okano 19:7a7381e78025 653 if ( target.readable() )
okano 19:7a7381e78025 654 *b++ = target.getc();
okano 19:7a7381e78025 655
okano 19:7a7381e78025 656 if ( timeout_flag )
okano 19:7a7381e78025 657 return ( i );
okano 19:7a7381e78025 658 }
okano 19:7a7381e78025 659
okano 19:7a7381e78025 660 return ( i );
okano 19:7a7381e78025 661 }
okano 19:7a7381e78025 662
okano 19:7a7381e78025 663
okano 16:cac2348cfcfb 664 void success_indicator()
okano 16:cac2348cfcfb 665 {
okano 16:cac2348cfcfb 666 static int i = 0;
okano 16:cac2348cfcfb 667
okano 16:cac2348cfcfb 668 leds = 0x1 << (i++ & 0x3);
okano 16:cac2348cfcfb 669 }
okano 16:cac2348cfcfb 670