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 03:09:09 2013 +0000
Revision:
21:e149d0bdbf4a
Parent:
20:98d7b5878e3e
Child:
22:bd98a782fba6
"command_utilities" module made

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