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:
Fri Sep 13 02:50:11 2013 +0000
Revision:
20:98d7b5878e3e
Parent:
19:7a7381e78025
Child:
21:e149d0bdbf4a
verification for uuencode type device (LPC1114) supported

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 20:98d7b5878e3e 67 target_param *open_target( int baud_date );
okano 20:98d7b5878e3e 68 int write_flash( FILE *fp, target_param *tpp );
okano 20:98d7b5878e3e 69 int verify_flash( FILE *fp, target_param *tpp );
okano 20:98d7b5878e3e 70 int post_writing_process( target_param *tpp );
okano 20:98d7b5878e3e 71
okano 7:815366f003ee 72 int file_size( FILE *fp );
okano 7:815366f003ee 73 void reset_target( int isp_pin_state );
okano 7:815366f003ee 74 int try_and_check( char *command, char *expected_return_str, int mode );
okano 7:815366f003ee 75 int try_and_check2( char *command, char *expected_return_str, int mode );
okano 7:815366f003ee 76 void print_command( char *command );
okano 7:815366f003ee 77 void print_result( int r );
okano 7:815366f003ee 78 char read_byte( void );
okano 7:815366f003ee 79 void erase_sectors( int last_sector );
okano 12:5a33b5d39792 80 int write_uuencoded_data( FILE *fp, int ram_size, int sector_size, unsigned int );
okano 12:5a33b5d39792 81 int write_binary_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start );
okano 19:7a7381e78025 82 int verify_binary_data( FILE *fp );
okano 20:98d7b5878e3e 83 int verify_uucoded_data( FILE *fp );
okano 20:98d7b5878e3e 84 void get_binary_from_uucode_str( char *b, int size );
okano 20:98d7b5878e3e 85 int uudecode_a_line( char *b, char *s );
okano 20:98d7b5878e3e 86 void initialize_uud_table( void );
okano 7:815366f003ee 87 void initialize_uue_table( void );
okano 11:8dfc3217d1ca 88 long bin2uue( char *bin, char *str, int size );
okano 12:5a33b5d39792 89 int get_flash_writing_size( int ram_size, unsigned int ram_start );
okano 7:815366f003ee 90 void add_isp_checksum( char *b );
okano 7:815366f003ee 91 void send_RAM_transfer_checksum( int checksum );
okano 7:815366f003ee 92 void put_string( char *s );
okano 12:5a33b5d39792 93 void put_binary( char *b, int size );
okano 7:815366f003ee 94 void get_string( char *s );
okano 19:7a7381e78025 95 int get_binary( char *b, int length );
okano 16:cac2348cfcfb 96 void success_indicator();
okano 7:815366f003ee 97
okano 19:7a7381e78025 98
okano 12:5a33b5d39792 99 #pragma diag_suppress 1293 // surpressing a warning message of "assignment in condition" ;)
okano 12:5a33b5d39792 100
okano 7:815366f003ee 101 int main()
okano 7:815366f003ee 102 {
okano 7:815366f003ee 103 FILE *fp;
okano 20:98d7b5878e3e 104 target_param *tpp;
okano 7:815366f003ee 105 int data_size;
okano 7:815366f003ee 106 int last_sector;
okano 8:b220fadbb3d8 107
okano 7:815366f003ee 108 printf( "\r\n\r\n\r\nmbed ISP program : programming LPC device from mbed\r\n" );
okano 7:815366f003ee 109
okano 20:98d7b5878e3e 110 if ( NULL == (tpp = open_target( ISP_BAUD_RATE )) )
okano 20:98d7b5878e3e 111 {
okano 20:98d7b5878e3e 112 error( "couldn't open the taget" );
okano 20:98d7b5878e3e 113 return ( 1 );
okano 20:98d7b5878e3e 114 }
okano 8:b220fadbb3d8 115
okano 8:b220fadbb3d8 116 printf( " target device found : type = \"%s\"\r\n", tpp->type_name );
okano 8:b220fadbb3d8 117 printf( " ID = 0x%08X\r\n", tpp->id );
okano 8:b220fadbb3d8 118 printf( " RAM size = %10d bytes\r\n", tpp->ram_size );
okano 8:b220fadbb3d8 119 printf( " flash size = %10d bytes\r\n", tpp->flash_size );
okano 8:b220fadbb3d8 120
okano 12:5a33b5d39792 121 printf( " opening file: \"%s\"\r\n", SOURCE_FILE );
okano 12:5a33b5d39792 122
okano 12:5a33b5d39792 123 if ( NULL == (fp = fopen( SOURCE_FILE, "rb" )) ) {
okano 12:5a33b5d39792 124 error( "couldn't open source file" );
okano 12:5a33b5d39792 125 return ( 1 );
okano 12:5a33b5d39792 126 }
okano 12:5a33b5d39792 127
okano 12:5a33b5d39792 128 data_size = file_size( fp );
okano 12:5a33b5d39792 129 last_sector = data_size / tpp->sector_size;
okano 12:5a33b5d39792 130
okano 12:5a33b5d39792 131 printf( " data size = %d bytes, it takes %d secotrs in flash area\r\n", data_size, last_sector + 1 );
okano 12:5a33b5d39792 132 printf( " resetting target\r\n" );
okano 12:5a33b5d39792 133
okano 7:815366f003ee 134 erase_sectors( last_sector );
okano 12:5a33b5d39792 135
okano 20:98d7b5878e3e 136 write_flash( fp, tpp );
okano 20:98d7b5878e3e 137 verify_flash( fp, tpp );
okano 12:5a33b5d39792 138
okano 7:815366f003ee 139 fclose( fp );
okano 8:b220fadbb3d8 140
okano 8:b220fadbb3d8 141 printf( "\r\n %s\r\n\r\n",
okano 8:b220fadbb3d8 142 error_state ?
okano 8:b220fadbb3d8 143 "** The data could not be written :(" :
okano 8:b220fadbb3d8 144 "** The data has been written successflly :)"
okano 8:b220fadbb3d8 145 );
okano 19:7a7381e78025 146
okano 19:7a7381e78025 147 if ( error_state )
okano 19:7a7381e78025 148 error( " ** ISP failed\r\n" );
okano 20:98d7b5878e3e 149
okano 20:98d7b5878e3e 150 post_writing_process( tpp );
okano 20:98d7b5878e3e 151
okano 8:b220fadbb3d8 152
okano 16:cac2348cfcfb 153 #define AUTO_PROGRAM_START
okano 14:a7b9f74fb856 154 #ifdef AUTO_PROGRAM_START
okano 16:cac2348cfcfb 155 target.baud( TARGET_OPERATION_BAUD_RATE );
okano 16:cac2348cfcfb 156
okano 14:a7b9f74fb856 157 reset_target( NO_ISP_MODE );
okano 16:cac2348cfcfb 158 printf( " ** The program in flash has been started!!\r\n" );
okano 14:a7b9f74fb856 159 #endif
okano 14:a7b9f74fb856 160
okano 16:cac2348cfcfb 161 printf( " (now the mbed is working in \"serial through mode\")\r\n\r\n" );
okano 16:cac2348cfcfb 162
okano 16:cac2348cfcfb 163 success.attach( &success_indicator, 0.1 );
okano 16:cac2348cfcfb 164
okano 16:cac2348cfcfb 165 while (1) {
okano 8:b220fadbb3d8 166
okano 16:cac2348cfcfb 167 if ( pc.readable() ) {
okano 16:cac2348cfcfb 168 target.putc( pc.getc() );
okano 16:cac2348cfcfb 169 }
okano 16:cac2348cfcfb 170
okano 16:cac2348cfcfb 171 if ( target.readable() ) {
okano 16:cac2348cfcfb 172 pc.putc( target.getc() );
okano 16:cac2348cfcfb 173 }
okano 20:98d7b5878e3e 174 }
okano 20:98d7b5878e3e 175 }
okano 16:cac2348cfcfb 176
okano 20:98d7b5878e3e 177
okano 20:98d7b5878e3e 178 target_param *open_target( int baud_date )
okano 20:98d7b5878e3e 179 {
okano 20:98d7b5878e3e 180 target_param *tpp;
okano 20:98d7b5878e3e 181 char str_buf0[ STR_BUFF_SIZE ];
okano 20:98d7b5878e3e 182 char str_buf1[ STR_BUFF_SIZE ];
okano 20:98d7b5878e3e 183
okano 20:98d7b5878e3e 184 target.baud( baud_date );
okano 20:98d7b5878e3e 185
okano 20:98d7b5878e3e 186 reset_target( ENTER_TO_ISP_MODE );
okano 20:98d7b5878e3e 187
okano 20:98d7b5878e3e 188 try_and_check( "?", "Synchronized", 0 );
okano 20:98d7b5878e3e 189
okano 20:98d7b5878e3e 190 try_and_check2( "Synchronized\r\n", "OK", 0 );
okano 20:98d7b5878e3e 191 try_and_check2( "12000\r\n", "OK", 0 );
okano 20:98d7b5878e3e 192 try_and_check2( "U 23130\r\n", "0", 0 );
okano 20:98d7b5878e3e 193 try_and_check2( "A 0\r\n", "0", 0 );
okano 20:98d7b5878e3e 194
okano 20:98d7b5878e3e 195 try_and_check( "K\r\n", "0", 0 );
okano 20:98d7b5878e3e 196 get_string( str_buf0 );
okano 20:98d7b5878e3e 197 get_string( str_buf1 );
okano 20:98d7b5878e3e 198
okano 20:98d7b5878e3e 199 printf( " result of \"K\" = %s %s\r\n", str_buf0, str_buf1 );
okano 20:98d7b5878e3e 200
okano 20:98d7b5878e3e 201 try_and_check( "J\r\n", "0", 0 );
okano 20:98d7b5878e3e 202 get_string( str_buf0 );
okano 20:98d7b5878e3e 203
okano 20:98d7b5878e3e 204 printf( " result of \"J\" = %s\r\n", str_buf0 );
okano 20:98d7b5878e3e 205
okano 20:98d7b5878e3e 206 tpp = find_target_param( str_buf0 );
okano 20:98d7b5878e3e 207
okano 20:98d7b5878e3e 208 return ( tpp );
okano 20:98d7b5878e3e 209 }
okano 20:98d7b5878e3e 210
okano 20:98d7b5878e3e 211
okano 20:98d7b5878e3e 212 int write_flash( FILE *fp, target_param *tpp )
okano 20:98d7b5878e3e 213 {
okano 20:98d7b5878e3e 214 if ( tpp->write_type == BINARY )
okano 20:98d7b5878e3e 215 write_binary_data( fp, tpp->ram_size, tpp->sector_size, tpp->ram_start_address );
okano 20:98d7b5878e3e 216 else // UUENCODE
okano 20:98d7b5878e3e 217 write_uuencoded_data( fp, tpp->ram_size, tpp->sector_size, tpp->ram_start_address );
okano 20:98d7b5878e3e 218 }
okano 20:98d7b5878e3e 219
okano 20:98d7b5878e3e 220 int verify_flash( FILE *fp, target_param *tpp )
okano 20:98d7b5878e3e 221 {
okano 20:98d7b5878e3e 222 if ( tpp->write_type == BINARY )
okano 20:98d7b5878e3e 223 verify_binary_data( fp );
okano 20:98d7b5878e3e 224 else
okano 20:98d7b5878e3e 225 verify_uucoded_data( fp );
okano 20:98d7b5878e3e 226 }
okano 20:98d7b5878e3e 227
okano 20:98d7b5878e3e 228
okano 20:98d7b5878e3e 229 int post_writing_process( target_param *tpp )
okano 20:98d7b5878e3e 230 {
okano 20:98d7b5878e3e 231 if ( tpp->write_type == UUENCODE )
okano 20:98d7b5878e3e 232 try_and_check( "G 0 T\r\n", "0", 0 );
okano 20:98d7b5878e3e 233
okano 7:815366f003ee 234 }
okano 7:815366f003ee 235
okano 7:815366f003ee 236
okano 7:815366f003ee 237 int file_size( FILE *fp )
okano 7:815366f003ee 238 {
okano 7:815366f003ee 239 int size;
okano 8:b220fadbb3d8 240
okano 7:815366f003ee 241 fseek( fp, 0, SEEK_END ); // seek to end of file
okano 7:815366f003ee 242 size = ftell( fp ); // get current file pointer
okano 7:815366f003ee 243 fseek( fp, 0, SEEK_SET ); // seek back to beginning of file
okano 8:b220fadbb3d8 244
okano 7:815366f003ee 245 return size;
okano 7:815366f003ee 246 }
okano 7:815366f003ee 247
okano 7:815366f003ee 248
okano 7:815366f003ee 249 void reset_target( int isp_pin_state )
okano 7:815366f003ee 250 {
okano 7:815366f003ee 251 reset_pin = 1;
okano 13:60995bf8b2c7 252 isp_pin = isp_pin_state;
okano 7:815366f003ee 253 wait_ms( 100 );
okano 13:60995bf8b2c7 254
okano 7:815366f003ee 255 reset_pin = 0;
okano 7:815366f003ee 256 wait_ms( 100 );
okano 13:60995bf8b2c7 257
okano 7:815366f003ee 258 reset_pin = 1;
okano 7:815366f003ee 259 wait_ms( 100 );
okano 7:815366f003ee 260 }
okano 7:815366f003ee 261
okano 7:815366f003ee 262
okano 7:815366f003ee 263 int try_and_check( char *command, char *expected_return_str, int mode )
okano 7:815366f003ee 264 {
okano 7:815366f003ee 265 char rtn_str[ STR_BUFF_SIZE ];
okano 8:b220fadbb3d8 266 int result = 1;
okano 8:b220fadbb3d8 267
okano 7:815366f003ee 268 print_command( command );
okano 7:815366f003ee 269 put_string( command );
okano 8:b220fadbb3d8 270
okano 7:815366f003ee 271 get_string( rtn_str );
okano 7:815366f003ee 272 print_result( result = strcmp( expected_return_str, rtn_str ) );
okano 8:b220fadbb3d8 273
okano 8:b220fadbb3d8 274 if ( result && !mode )
okano 8:b220fadbb3d8 275 error( "command failed\r\n" );
okano 8:b220fadbb3d8 276
okano 8:b220fadbb3d8 277 error_state |= result;
okano 8:b220fadbb3d8 278
okano 7:815366f003ee 279 return ( result );
okano 7:815366f003ee 280 }
okano 7:815366f003ee 281
okano 7:815366f003ee 282
okano 7:815366f003ee 283 int try_and_check2( char *command, char *expected_return_str, int mode )
okano 7:815366f003ee 284 {
okano 7:815366f003ee 285 char rtn_str[ STR_BUFF_SIZE ];
okano 8:b220fadbb3d8 286 int result = 1;
okano 8:b220fadbb3d8 287
okano 7:815366f003ee 288 print_command( command );
okano 7:815366f003ee 289 put_string( command );
okano 8:b220fadbb3d8 290
okano 7:815366f003ee 291 get_string( rtn_str ); // just readout echoback
okano 7:815366f003ee 292 get_string( rtn_str );
okano 7:815366f003ee 293 print_result( result = strcmp( expected_return_str, rtn_str ) );
okano 8:b220fadbb3d8 294
okano 8:b220fadbb3d8 295 if ( result && !mode )
okano 8:b220fadbb3d8 296 error( "command failed\r\n" );
okano 8:b220fadbb3d8 297
okano 8:b220fadbb3d8 298 error_state |= result;
okano 8:b220fadbb3d8 299
okano 7:815366f003ee 300 return ( result );
okano 7:815366f003ee 301 }
okano 7:815366f003ee 302
okano 7:815366f003ee 303
okano 7:815366f003ee 304 void print_command( char *command )
okano 7:815366f003ee 305 {
okano 7:815366f003ee 306 char s[ STR_BUFF_SIZE ];
okano 7:815366f003ee 307 char *pos;
okano 8:b220fadbb3d8 308
okano 7:815366f003ee 309 strcpy( s, command );
okano 8:b220fadbb3d8 310
okano 7:815366f003ee 311 if ( pos = strchr( s, '\r' ) )
okano 7:815366f003ee 312 *pos = '\0';
okano 8:b220fadbb3d8 313
okano 7:815366f003ee 314 if ( pos = strchr( s, '\n' ) )
okano 7:815366f003ee 315 *pos = '\0';
okano 8:b220fadbb3d8 316
okano 7:815366f003ee 317 printf( " command-\"%s\" : ", s );
okano 7:815366f003ee 318 }
okano 7:815366f003ee 319
okano 7:815366f003ee 320
okano 7:815366f003ee 321 void print_result( int r )
okano 7:815366f003ee 322 {
okano 7:815366f003ee 323 printf( "%s\r\n", r ? "Fail" : "Pass" );
okano 7:815366f003ee 324 }
okano 7:815366f003ee 325
okano 7:815366f003ee 326
okano 7:815366f003ee 327 char read_byte( void )
okano 7:815366f003ee 328 {
okano 7:815366f003ee 329 while ( !target.readable() )
okano 7:815366f003ee 330 ;
okano 8:b220fadbb3d8 331
okano 7:815366f003ee 332 return ( target.getc() );
okano 7:815366f003ee 333 }
okano 7:815366f003ee 334
okano 7:815366f003ee 335
okano 7:815366f003ee 336 void erase_sectors( int last_sector )
okano 7:815366f003ee 337 {
okano 7:815366f003ee 338 char command_str[ STR_BUFF_SIZE ];
okano 8:b220fadbb3d8 339
okano 7:815366f003ee 340 sprintf( command_str, "P 0 %d\r\n", last_sector );
okano 7:815366f003ee 341 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 342
okano 7:815366f003ee 343 *(command_str) = 'E';
okano 7:815366f003ee 344 try_and_check( command_str, "0", 0 );
okano 7:815366f003ee 345 }
okano 7:815366f003ee 346
okano 12:5a33b5d39792 347 #define BYTES_PER_LINE 45
okano 20:98d7b5878e3e 348 char uu_table[ 0x60 + 1 ];
okano 7:815366f003ee 349
okano 12:5a33b5d39792 350 int write_uuencoded_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start )
okano 7:815366f003ee 351 {
okano 7:815366f003ee 352 char command_str[ STR_BUFF_SIZE ];
okano 7:815366f003ee 353 long checksum = 0;
okano 7:815366f003ee 354 int total_size = 0;
okano 7:815366f003ee 355 int size;
okano 8:b220fadbb3d8 356
okano 7:815366f003ee 357 int flash_writing_size;
okano 7:815366f003ee 358 int lines_per_transfer;
okano 7:815366f003ee 359 int transfer_size;
okano 8:b220fadbb3d8 360
okano 12:5a33b5d39792 361 char *b;
okano 12:5a33b5d39792 362
okano 7:815366f003ee 363 initialize_uue_table();
okano 8:b220fadbb3d8 364
okano 12:5a33b5d39792 365 flash_writing_size = get_flash_writing_size( ram_size, ram_start );
okano 11:8dfc3217d1ca 366 lines_per_transfer = ((flash_writing_size / BYTES_PER_LINE) + 1);
okano 11:8dfc3217d1ca 367 transfer_size = (((flash_writing_size + 11) / 12) * 12);
okano 8:b220fadbb3d8 368
okano 7:815366f003ee 369 // char b[ transfer_size ]; // this can be done in mbed-compiler. but I should do it in common way
okano 8:b220fadbb3d8 370
okano 7:815366f003ee 371 if ( NULL == (b = (char *)malloc( transfer_size * sizeof( char ) )) )
okano 7:815366f003ee 372 error( "malloc error happened\r\n" );
okano 8:b220fadbb3d8 373
okano 7:815366f003ee 374 for ( int i = flash_writing_size; i < transfer_size; i++ )
okano 7:815366f003ee 375 b[ i ] = 0; // this is not neccesary but just stuffing stuffing bytes
okano 8:b220fadbb3d8 376
okano 7:815366f003ee 377 while ( size = fread( b, sizeof( char ), flash_writing_size, fp ) ) {
okano 8:b220fadbb3d8 378
okano 7:815366f003ee 379 if ( !total_size ) {
okano 7:815366f003ee 380 // overwriting 4 bytes data for address=0x1C
okano 7:815366f003ee 381 // there is a slot for checksum that is checked in (target's) boot process
okano 7:815366f003ee 382 add_isp_checksum( b );
okano 7:815366f003ee 383 }
okano 8:b220fadbb3d8 384
okano 12:5a33b5d39792 385 sprintf( command_str, "W %ld %ld\r\n", ram_start, transfer_size );
okano 7:815366f003ee 386 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 387
okano 7:815366f003ee 388 for ( int i = 0; i < lines_per_transfer; i++ ) {
okano 12:5a33b5d39792 389
okano 11:8dfc3217d1ca 390 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 391
okano 13:60995bf8b2c7 392 // printf( " data -- %02d %s\r", i, command_str );
okano 8:b220fadbb3d8 393
okano 7:815366f003ee 394 put_string( command_str );
okano 8:b220fadbb3d8 395
okano 7:815366f003ee 396 if ( !((i + 1) % 20) ) {
okano 7:815366f003ee 397 send_RAM_transfer_checksum( checksum );
okano 7:815366f003ee 398 checksum = 0;
okano 7:815366f003ee 399 }
okano 7:815366f003ee 400 }
okano 8:b220fadbb3d8 401
okano 7:815366f003ee 402 send_RAM_transfer_checksum( checksum );
okano 7:815366f003ee 403 checksum = 0;
okano 8:b220fadbb3d8 404
okano 12:5a33b5d39792 405 sprintf( command_str, "P %d %d\r\n", total_size / sector_size, total_size / sector_size );
okano 7:815366f003ee 406 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 407
okano 12:5a33b5d39792 408 sprintf( command_str, "C %d %d %d\r\n", total_size, ram_start, flash_writing_size );
okano 7:815366f003ee 409 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 410
okano 7:815366f003ee 411 total_size += size;
okano 7:815366f003ee 412 }
okano 8:b220fadbb3d8 413
okano 7:815366f003ee 414 free( b );
okano 8:b220fadbb3d8 415
okano 12:5a33b5d39792 416 return ( total_size );
okano 7:815366f003ee 417 }
okano 7:815366f003ee 418
okano 7:815366f003ee 419
okano 12:5a33b5d39792 420 int write_binary_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start )
okano 12:5a33b5d39792 421 {
okano 12:5a33b5d39792 422 char command_str[ STR_BUFF_SIZE ];
okano 12:5a33b5d39792 423 int total_size = 0;
okano 12:5a33b5d39792 424 int size;
okano 12:5a33b5d39792 425 int flash_writing_size;
okano 12:5a33b5d39792 426 char *b;
okano 12:5a33b5d39792 427
okano 12:5a33b5d39792 428 flash_writing_size = 256;
okano 12:5a33b5d39792 429
okano 12:5a33b5d39792 430 if ( NULL == (b = (char *)malloc( flash_writing_size * sizeof( char ) )) )
okano 12:5a33b5d39792 431 error( "malloc error happened\r\n" );
okano 12:5a33b5d39792 432
okano 19:7a7381e78025 433 printf( "\r\n ==== flash writing ====\r\n" );
okano 19:7a7381e78025 434
okano 12:5a33b5d39792 435 while ( size = fread( b, sizeof( char ), flash_writing_size, fp ) ) {
okano 12:5a33b5d39792 436
okano 12:5a33b5d39792 437 if ( !total_size ) {
okano 12:5a33b5d39792 438 // overwriting 4 bytes data for address=0x1C
okano 12:5a33b5d39792 439 // there is a slot for checksum that is checked in (target's) boot process
okano 12:5a33b5d39792 440 add_isp_checksum( b );
okano 12:5a33b5d39792 441 }
okano 12:5a33b5d39792 442
okano 12:5a33b5d39792 443 sprintf( command_str, "W %ld %ld\r\n", ram_start, flash_writing_size );
okano 12:5a33b5d39792 444 try_and_check( command_str, "0", 0 );
okano 12:5a33b5d39792 445
okano 12:5a33b5d39792 446 put_binary( b, flash_writing_size );
okano 12:5a33b5d39792 447 put_string( "\r\n" );
okano 12:5a33b5d39792 448
okano 12:5a33b5d39792 449 sprintf( command_str, "P %d %d\r\n", total_size / sector_size, total_size / sector_size );
okano 12:5a33b5d39792 450 try_and_check( command_str, "0", 0 );
okano 12:5a33b5d39792 451
okano 12:5a33b5d39792 452 sprintf( command_str, "C %d %d %d\r\n", total_size, ram_start, flash_writing_size );
okano 12:5a33b5d39792 453 try_and_check( command_str, "0", 0 );
okano 12:5a33b5d39792 454
okano 12:5a33b5d39792 455 total_size += size;
okano 19:7a7381e78025 456 //printf( " total %d bytes transferred\r", total_size );
okano 12:5a33b5d39792 457
okano 12:5a33b5d39792 458 }
okano 12:5a33b5d39792 459
okano 12:5a33b5d39792 460 free( b );
okano 12:5a33b5d39792 461
okano 12:5a33b5d39792 462 return ( total_size );
okano 12:5a33b5d39792 463 }
okano 12:5a33b5d39792 464
okano 19:7a7381e78025 465
okano 19:7a7381e78025 466 int verify_binary_data( FILE *fp )
okano 19:7a7381e78025 467 {
okano 19:7a7381e78025 468 char command_str[ STR_BUFF_SIZE ];
okano 19:7a7381e78025 469 int read_size = 0;
okano 19:7a7381e78025 470 int size;
okano 19:7a7381e78025 471 int flash_reading_size;
okano 19:7a7381e78025 472 char *bf;
okano 19:7a7381e78025 473 char *br;
okano 19:7a7381e78025 474 int error_flag = 0;
okano 19:7a7381e78025 475 unsigned long checksum = 0;
okano 19:7a7381e78025 476 unsigned long checksum_count = 0;
okano 19:7a7381e78025 477
okano 19:7a7381e78025 478 fseek( fp, 0, SEEK_SET ); // seek back to beginning of file
okano 19:7a7381e78025 479
okano 19:7a7381e78025 480 flash_reading_size = 128;
okano 19:7a7381e78025 481
okano 19:7a7381e78025 482 if ( NULL == (bf = (char *)malloc( flash_reading_size * sizeof( char ) )) )
okano 19:7a7381e78025 483 error( "malloc error happened (in verify process, file data buffer)\r\n" );
okano 19:7a7381e78025 484
okano 19:7a7381e78025 485 if ( NULL == (br = (char *)malloc( flash_reading_size * sizeof( char ) )) )
okano 19:7a7381e78025 486 error( "malloc error happened (in verify process, read data buffer)\r\n" );
okano 19:7a7381e78025 487
okano 19:7a7381e78025 488
okano 19:7a7381e78025 489 printf( "\r\n ==== flash reading and verifying ====\r\n" );
okano 19:7a7381e78025 490
okano 19:7a7381e78025 491 while ( size = fread( bf, sizeof( char ), flash_reading_size, fp ) ) {
okano 19:7a7381e78025 492
okano 19:7a7381e78025 493 if ( read_size < 0x20 ) {
okano 19:7a7381e78025 494 for ( int i = 0; i < flash_reading_size; i += 4 ) {
okano 19:7a7381e78025 495
okano 19:7a7381e78025 496 if ( checksum_count == 7 ) {
okano 19:7a7381e78025 497 checksum = 0xFFFFFFFF - checksum + 1;
okano 19:7a7381e78025 498 *((unsigned int *)(bf + i)) = checksum;
okano 19:7a7381e78025 499 //printf( "\r\n\r\n -- calculated checksum : 0x%08X\r\n", checksum );
okano 19:7a7381e78025 500 } else {
okano 19:7a7381e78025 501 checksum += *((unsigned int *)(bf + i));
okano 19:7a7381e78025 502 }
okano 19:7a7381e78025 503
okano 19:7a7381e78025 504 checksum_count++;
okano 19:7a7381e78025 505 }
okano 19:7a7381e78025 506 }
okano 19:7a7381e78025 507
okano 19:7a7381e78025 508
okano 19:7a7381e78025 509 sprintf( command_str, "R %ld %ld\r\n", read_size, size );
okano 19:7a7381e78025 510 // try_and_check( command_str, "0", MODE_SILENT );
okano 19:7a7381e78025 511 try_and_check( command_str, "0", 0 );
okano 19:7a7381e78025 512
okano 19:7a7381e78025 513 get_binary( br, 1 );
okano 19:7a7381e78025 514 get_binary( br, size );
okano 19:7a7381e78025 515
okano 19:7a7381e78025 516 for ( int i = 0; i < size; i++ ) {
okano 19:7a7381e78025 517 // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) );
okano 19:7a7381e78025 518 if ( (*(bf + i) != *(br + i)) ) {
okano 19:7a7381e78025 519 // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) );
okano 19:7a7381e78025 520 error_flag++;
okano 19:7a7381e78025 521 }
okano 19:7a7381e78025 522 }
okano 19:7a7381e78025 523
okano 19:7a7381e78025 524 if ( error_flag )
okano 19:7a7381e78025 525 break;
okano 19:7a7381e78025 526
okano 19:7a7381e78025 527 read_size += size;
okano 19:7a7381e78025 528
okano 19:7a7381e78025 529 // printf( " total %d bytes read\r\n", read_size );
okano 19:7a7381e78025 530 }
okano 19:7a7381e78025 531
okano 19:7a7381e78025 532 error_state |= error_flag;
okano 19:7a7381e78025 533
okano 19:7a7381e78025 534 printf( " total %d bytes read\r", read_size );
okano 19:7a7381e78025 535 printf( " verification result : \"%s\"\r\n", error_flag ? "Fail" : "Pass" );
okano 19:7a7381e78025 536
okano 19:7a7381e78025 537 free( bf );
okano 19:7a7381e78025 538 free( br );
okano 19:7a7381e78025 539
okano 19:7a7381e78025 540 return ( read_size );
okano 19:7a7381e78025 541 }
okano 19:7a7381e78025 542
okano 19:7a7381e78025 543
okano 20:98d7b5878e3e 544 int verify_uucoded_data( FILE *fp )
okano 20:98d7b5878e3e 545 {
okano 20:98d7b5878e3e 546 char command_str[ STR_BUFF_SIZE ];
okano 20:98d7b5878e3e 547 int read_size = 0;
okano 20:98d7b5878e3e 548 int size;
okano 20:98d7b5878e3e 549 int flash_reading_size;
okano 20:98d7b5878e3e 550 char *bf;
okano 20:98d7b5878e3e 551 char *br;
okano 20:98d7b5878e3e 552 int error_flag = 0;
okano 20:98d7b5878e3e 553
okano 20:98d7b5878e3e 554 flash_reading_size = 176;
okano 20:98d7b5878e3e 555
okano 20:98d7b5878e3e 556 if ( NULL == (bf = (char *)malloc( flash_reading_size * sizeof( char ) )) )
okano 20:98d7b5878e3e 557 error( "malloc error happened (in verify process, file data buffer)\r\n" );
okano 20:98d7b5878e3e 558
okano 20:98d7b5878e3e 559 if ( NULL == (br = (char *)malloc( flash_reading_size * sizeof( char ) )) )
okano 20:98d7b5878e3e 560 error( "malloc error happened (in verify process, read data buffer)\r\n" );
okano 20:98d7b5878e3e 561
okano 20:98d7b5878e3e 562 fseek( fp, 0, SEEK_SET ); // seek back to beginning of file
okano 20:98d7b5878e3e 563
okano 20:98d7b5878e3e 564 while ( size = fread( bf, sizeof( char ), flash_reading_size, fp ) ) {
okano 20:98d7b5878e3e 565
okano 20:98d7b5878e3e 566 if ( !read_size ) {
okano 20:98d7b5878e3e 567 // overwriting 4 bytes data for address=0x1C
okano 20:98d7b5878e3e 568 // there is a slot for checksum that is checked in (target's) boot process
okano 20:98d7b5878e3e 569 add_isp_checksum( bf );
okano 20:98d7b5878e3e 570 }
okano 20:98d7b5878e3e 571
okano 20:98d7b5878e3e 572 sprintf( command_str, "R %ld %ld\r\n", read_size, size );
okano 20:98d7b5878e3e 573 try_and_check( command_str, "0", 0 );
okano 20:98d7b5878e3e 574
okano 20:98d7b5878e3e 575 get_binary_from_uucode_str( br, size );
okano 20:98d7b5878e3e 576
okano 20:98d7b5878e3e 577 for ( int i = 0; i < size; i++ ) {
okano 20:98d7b5878e3e 578 // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) );
okano 20:98d7b5878e3e 579 if ( (*(bf + i) != *(br + i)) ) {
okano 20:98d7b5878e3e 580 printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) );
okano 20:98d7b5878e3e 581 error_flag++;
okano 20:98d7b5878e3e 582 }
okano 20:98d7b5878e3e 583 }
okano 20:98d7b5878e3e 584
okano 20:98d7b5878e3e 585 if ( error_flag )
okano 20:98d7b5878e3e 586 break;
okano 20:98d7b5878e3e 587
okano 20:98d7b5878e3e 588 read_size += size;
okano 20:98d7b5878e3e 589 // printf( " total %d bytes read\r", read_size );
okano 20:98d7b5878e3e 590 }
okano 20:98d7b5878e3e 591
okano 20:98d7b5878e3e 592 error_state |= error_flag;
okano 20:98d7b5878e3e 593
okano 20:98d7b5878e3e 594 printf( " total %d bytes read\r", read_size );
okano 20:98d7b5878e3e 595 printf( " verification result : \"%s\"\r\n", error_flag ? "Fail" : "Pass" );
okano 20:98d7b5878e3e 596
okano 20:98d7b5878e3e 597 free( bf );
okano 20:98d7b5878e3e 598 free( br );
okano 20:98d7b5878e3e 599
okano 20:98d7b5878e3e 600 return ( read_size );
okano 20:98d7b5878e3e 601 }
okano 20:98d7b5878e3e 602
okano 20:98d7b5878e3e 603
okano 20:98d7b5878e3e 604 void get_binary_from_uucode_str( char *b, int size )
okano 20:98d7b5878e3e 605 {
okano 20:98d7b5878e3e 606 #define N 4
okano 20:98d7b5878e3e 607
okano 20:98d7b5878e3e 608 char s[ N ][ STR_BUFF_SIZE ];
okano 20:98d7b5878e3e 609 char ss[ STR_BUFF_SIZE ];
okano 20:98d7b5878e3e 610 long checksum = 0;
okano 20:98d7b5878e3e 611 int line_count = 0;
okano 20:98d7b5878e3e 612 int read_size = 0;
okano 20:98d7b5878e3e 613 int retry_count = 3;
okano 20:98d7b5878e3e 614
okano 20:98d7b5878e3e 615 initialize_uud_table();
okano 20:98d7b5878e3e 616
okano 20:98d7b5878e3e 617 while ( retry_count-- ) {
okano 20:98d7b5878e3e 618
okano 20:98d7b5878e3e 619 for ( int i = 0; i < N; i++ )
okano 20:98d7b5878e3e 620 get_string( s[ i ] );
okano 20:98d7b5878e3e 621
okano 20:98d7b5878e3e 622 get_string( ss );
okano 20:98d7b5878e3e 623
okano 20:98d7b5878e3e 624
okano 20:98d7b5878e3e 625 while ( size ) {
okano 20:98d7b5878e3e 626 read_size = uudecode_a_line( b, s[ line_count ] );
okano 20:98d7b5878e3e 627
okano 20:98d7b5878e3e 628 for ( int i = 0; i < read_size; i++ )
okano 20:98d7b5878e3e 629 checksum += *b++;
okano 20:98d7b5878e3e 630
okano 20:98d7b5878e3e 631 size -= read_size;
okano 20:98d7b5878e3e 632 line_count++;
okano 20:98d7b5878e3e 633 }
okano 20:98d7b5878e3e 634
okano 20:98d7b5878e3e 635 // printf( " checksum -- %s (internal = %ld)\r\n", ss, checksum );
okano 20:98d7b5878e3e 636
okano 20:98d7b5878e3e 637 if ( checksum == atol( ss ) ) {
okano 20:98d7b5878e3e 638 put_string( "OK\r\n" );
okano 20:98d7b5878e3e 639 return;
okano 20:98d7b5878e3e 640 // printf( " checksum OK\r\n" );
okano 20:98d7b5878e3e 641 } else {
okano 20:98d7b5878e3e 642 printf( " checksum RESEND\r\n" );
okano 20:98d7b5878e3e 643 put_string( "RESEND\r\n" );
okano 20:98d7b5878e3e 644 }
okano 20:98d7b5878e3e 645 }
okano 20:98d7b5878e3e 646 }
okano 20:98d7b5878e3e 647
okano 20:98d7b5878e3e 648
okano 20:98d7b5878e3e 649 int uudecode_a_line( char *b, char *s )
okano 20:98d7b5878e3e 650 {
okano 20:98d7b5878e3e 651
okano 20:98d7b5878e3e 652 unsigned long v;
okano 20:98d7b5878e3e 653 int read_size;
okano 20:98d7b5878e3e 654
okano 20:98d7b5878e3e 655 read_size = (*s++) - ' ';
okano 20:98d7b5878e3e 656
okano 20:98d7b5878e3e 657 for ( int i = 0; i < read_size; i += 3 ) {
okano 20:98d7b5878e3e 658 v = uu_table[ *s++ ] << 18;
okano 20:98d7b5878e3e 659 v |= uu_table[ *s++ ] << 12;
okano 20:98d7b5878e3e 660 v |= uu_table[ *s++ ] << 6;
okano 20:98d7b5878e3e 661 v |= uu_table[ *s++ ] << 0;
okano 20:98d7b5878e3e 662
okano 20:98d7b5878e3e 663 *b++ = (v >> 16) & 0xFF;
okano 20:98d7b5878e3e 664 *b++ = (v >> 8) & 0xFF;
okano 20:98d7b5878e3e 665 *b++ = (v >> 0) & 0xFF;
okano 20:98d7b5878e3e 666 }
okano 20:98d7b5878e3e 667
okano 20:98d7b5878e3e 668 return ( read_size );
okano 20:98d7b5878e3e 669 }
okano 20:98d7b5878e3e 670
okano 20:98d7b5878e3e 671
okano 7:815366f003ee 672 void initialize_uue_table( void )
okano 7:815366f003ee 673 {
okano 7:815366f003ee 674 int i;
okano 8:b220fadbb3d8 675
okano 20:98d7b5878e3e 676 uu_table[ 0 ] = 0x60; // 0x20 is translated to 0x60 !
okano 20:98d7b5878e3e 677
okano 20:98d7b5878e3e 678 for ( i = 1; i < 64; i++ ) {
okano 20:98d7b5878e3e 679 uu_table[ i ] = (char)(' ' + i);
okano 20:98d7b5878e3e 680 }
okano 20:98d7b5878e3e 681 }
okano 20:98d7b5878e3e 682
okano 8:b220fadbb3d8 683
okano 20:98d7b5878e3e 684 void initialize_uud_table( void )
okano 20:98d7b5878e3e 685 {
okano 20:98d7b5878e3e 686 int i;
okano 20:98d7b5878e3e 687
okano 20:98d7b5878e3e 688 uu_table[ 0x60 ] = 0;
okano 20:98d7b5878e3e 689
okano 20:98d7b5878e3e 690 for ( i = 0x21; i < 0x60; i++ ) {
okano 20:98d7b5878e3e 691 uu_table[ i ] = i - 0x20;
okano 7:815366f003ee 692 }
okano 7:815366f003ee 693 }
okano 7:815366f003ee 694
okano 7:815366f003ee 695
okano 11:8dfc3217d1ca 696 long bin2uue( char *bin, char *str, int size )
okano 7:815366f003ee 697 {
okano 7:815366f003ee 698 unsigned long v;
okano 7:815366f003ee 699 long checksum = 0;
okano 7:815366f003ee 700 int strpos = 0;
okano 8:b220fadbb3d8 701
okano 11:8dfc3217d1ca 702 *(str + strpos++) = ' ' + size;
okano 8:b220fadbb3d8 703
okano 11:8dfc3217d1ca 704 for ( int i = 0; i < size; i += 3 ) {
okano 7:815366f003ee 705 checksum += *(bin + i + 0) + *(bin + i + 1) + *(bin + i + 2);
okano 7:815366f003ee 706 v = (*(bin + i + 0) << 16) | (*(bin + i + 1) << 8) | (*(bin + i + 2) << 0);
okano 20:98d7b5878e3e 707 *(str + strpos++) = uu_table[ (v >> 18) & 0x3F ];
okano 20:98d7b5878e3e 708 *(str + strpos++) = uu_table[ (v >> 12) & 0x3F ];
okano 20:98d7b5878e3e 709 *(str + strpos++) = uu_table[ (v >> 6) & 0x3F ];
okano 20:98d7b5878e3e 710 *(str + strpos++) = uu_table[ (v >> 0) & 0x3F ];
okano 7:815366f003ee 711 }
okano 7:815366f003ee 712 *(str + strpos++) = '\n';
okano 7:815366f003ee 713 *(str + strpos++) = '\0';
okano 8:b220fadbb3d8 714
okano 7:815366f003ee 715 return checksum;
okano 7:815366f003ee 716 }
okano 6:0ae6fe8c8512 717
okano 6:0ae6fe8c8512 718
okano 12:5a33b5d39792 719 int get_flash_writing_size( int ram_size, unsigned int ram_start )
okano 6:0ae6fe8c8512 720 {
okano 6:0ae6fe8c8512 721 int flash_writing_size[] = {
okano 6:0ae6fe8c8512 722 4096,
okano 6:0ae6fe8c8512 723 1024,
okano 6:0ae6fe8c8512 724 512,
okano 6:0ae6fe8c8512 725 256
okano 6:0ae6fe8c8512 726 };
okano 6:0ae6fe8c8512 727 int available_size;
okano 6:0ae6fe8c8512 728 int i;
okano 8:b220fadbb3d8 729
okano 12:5a33b5d39792 730 available_size = ram_size - (ram_start & 0xFFFF);
okano 8:b220fadbb3d8 731
okano 6:0ae6fe8c8512 732 for ( i = 0; i < sizeof( flash_writing_size ) / sizeof( int ); i++ ) {
okano 6:0ae6fe8c8512 733 if ( flash_writing_size[ i ] < available_size )
okano 6:0ae6fe8c8512 734 break;
okano 6:0ae6fe8c8512 735 }
okano 8:b220fadbb3d8 736
okano 6:0ae6fe8c8512 737 return ( flash_writing_size[ i ] );
okano 6:0ae6fe8c8512 738 }
okano 4:55f1977bd11a 739
okano 4:55f1977bd11a 740
okano 1:54e619428ae6 741 void add_isp_checksum( char *b )
okano 1:54e619428ae6 742 {
okano 1:54e619428ae6 743 // see http://www.lpcware.com/content/nxpfile/lpc177x8x-checksum-insertion-program
okano 8:b220fadbb3d8 744
okano 1:54e619428ae6 745 unsigned int *p;
okano 1:54e619428ae6 746 unsigned int cksum = 0;
okano 8:b220fadbb3d8 747
okano 1:54e619428ae6 748 p = (unsigned int *)b;
okano 8:b220fadbb3d8 749
okano 1:54e619428ae6 750 for ( int i = 0; i < 7; i++ ) {
okano 1:54e619428ae6 751 cksum += *p++;
okano 1:54e619428ae6 752 }
okano 8:b220fadbb3d8 753
okano 1:54e619428ae6 754 printf( " -- value at checksum slot : 0x%08X\r\n", *p );
okano 8:b220fadbb3d8 755
okano 1:54e619428ae6 756 *p = 0xFFFFFFFF - cksum + 1;
okano 1:54e619428ae6 757 printf( " -- calculated checksum : 0x%08X\r\n", *p );
okano 8:b220fadbb3d8 758
okano 1:54e619428ae6 759 printf( " new checksum will be used to program flash\r\n" );
okano 1:54e619428ae6 760 }
okano 1:54e619428ae6 761
okano 1:54e619428ae6 762
okano 4:55f1977bd11a 763 void send_RAM_transfer_checksum( int checksum )
okano 4:55f1977bd11a 764 {
okano 4:55f1977bd11a 765 char command[ 16 ];
okano 8:b220fadbb3d8 766
okano 4:55f1977bd11a 767 sprintf( command, "%d\n", checksum );
okano 4:55f1977bd11a 768 try_and_check( command, "OK", 0 );
okano 4:55f1977bd11a 769 }
okano 4:55f1977bd11a 770
okano 0:6baefda2e511 771
okano 0:6baefda2e511 772 void put_string( char *s )
okano 0:6baefda2e511 773 {
okano 2:8d75eb0ecd20 774 char c;
okano 2:8d75eb0ecd20 775 static int i = 0;
okano 8:b220fadbb3d8 776
okano 3:3c380e643e74 777 while ( c = *s++ ) {
okano 0:6baefda2e511 778 target.putc( c );
okano 2:8d75eb0ecd20 779 leds = i++ & 0x1;
okano 2:8d75eb0ecd20 780 }
okano 0:6baefda2e511 781 }
okano 0:6baefda2e511 782
okano 7:815366f003ee 783
okano 12:5a33b5d39792 784 void put_binary( char *b, int size )
okano 12:5a33b5d39792 785 {
okano 12:5a33b5d39792 786 for ( int i = 0; i < size; i++ )
okano 12:5a33b5d39792 787 target.putc( *b++ );
okano 12:5a33b5d39792 788 }
okano 12:5a33b5d39792 789
okano 12:5a33b5d39792 790
okano 9:ca4c9a2ac8e1 791 Timeout timeout;
okano 9:ca4c9a2ac8e1 792
okano 9:ca4c9a2ac8e1 793 int timeout_flag = 0;
okano 9:ca4c9a2ac8e1 794
okano 9:ca4c9a2ac8e1 795 void set_flag()
okano 9:ca4c9a2ac8e1 796 {
okano 9:ca4c9a2ac8e1 797 timeout_flag = 1;
okano 9:ca4c9a2ac8e1 798 }
okano 9:ca4c9a2ac8e1 799
okano 9:ca4c9a2ac8e1 800
okano 0:6baefda2e511 801 void get_string( char *s )
okano 0:6baefda2e511 802 {
okano 0:6baefda2e511 803 int i = 0;
okano 0:6baefda2e511 804 char c = 0;
okano 9:ca4c9a2ac8e1 805 timeout_flag = 0;
okano 9:ca4c9a2ac8e1 806
okano 9:ca4c9a2ac8e1 807 timeout.attach( &set_flag, 1 );
okano 8:b220fadbb3d8 808
okano 0:6baefda2e511 809 do {
okano 0:6baefda2e511 810 do {
okano 0:6baefda2e511 811 if ( target.readable() ) {
okano 0:6baefda2e511 812 c = target.getc();
okano 8:b220fadbb3d8 813
okano 0:6baefda2e511 814 if ( ( c == '\n') || (c == '\r') )
okano 0:6baefda2e511 815 break;
okano 8:b220fadbb3d8 816
okano 0:6baefda2e511 817 *s++ = c;
okano 0:6baefda2e511 818 i++;
okano 0:6baefda2e511 819 }
okano 9:ca4c9a2ac8e1 820
okano 9:ca4c9a2ac8e1 821 if ( timeout_flag )
okano 9:ca4c9a2ac8e1 822 return;
okano 0:6baefda2e511 823 } while ( 1 );
okano 0:6baefda2e511 824 } while ( !i );
okano 8:b220fadbb3d8 825
okano 0:6baefda2e511 826 *s = '\0';
okano 0:6baefda2e511 827 }
okano 9:ca4c9a2ac8e1 828
okano 16:cac2348cfcfb 829
okano 19:7a7381e78025 830 int get_binary( char *b, int length )
okano 19:7a7381e78025 831 {
okano 19:7a7381e78025 832 int i;
okano 19:7a7381e78025 833
okano 19:7a7381e78025 834 timeout_flag = 0;
okano 19:7a7381e78025 835 timeout.attach( &set_flag, 1 );
okano 19:7a7381e78025 836
okano 19:7a7381e78025 837 for ( i = 0; i < length; i++ ) {
okano 19:7a7381e78025 838 if ( target.readable() )
okano 19:7a7381e78025 839 *b++ = target.getc();
okano 19:7a7381e78025 840
okano 19:7a7381e78025 841 if ( timeout_flag )
okano 19:7a7381e78025 842 return ( i );
okano 19:7a7381e78025 843 }
okano 19:7a7381e78025 844
okano 19:7a7381e78025 845 return ( i );
okano 19:7a7381e78025 846 }
okano 19:7a7381e78025 847
okano 19:7a7381e78025 848
okano 16:cac2348cfcfb 849 void success_indicator()
okano 16:cac2348cfcfb 850 {
okano 16:cac2348cfcfb 851 static int i = 0;
okano 16:cac2348cfcfb 852
okano 16:cac2348cfcfb 853 leds = 0x1 << (i++ & 0x3);
okano 16:cac2348cfcfb 854 }