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:41:11 2013 +0000
Revision:
23:017f306cf3ca
Parent:
22:bd98a782fba6
Child:
24:9830b4f1207b
dividing code into modules

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 22:bd98a782fba6 26 #include "serial_utilities.h"
okano 22:bd98a782fba6 27 #include "command_interface.h"
okano 22:bd98a782fba6 28 #include "writing.h"
okano 22:bd98a782fba6 29 #include "uu_coding.h"
okano 23:017f306cf3ca 30 #include "target_handling.h"
okano 21:e149d0bdbf4a 31 #include "ika.h"
okano 21:e149d0bdbf4a 32
okano 0:6baefda2e511 33
okano 2:8d75eb0ecd20 34 BusOut leds( LED4, LED3, LED2, LED1 );
okano 2:8d75eb0ecd20 35 LocalFileSystem local( "local" );
okano 16:cac2348cfcfb 36 Ticker success;
okano 0:6baefda2e511 37
okano 19:7a7381e78025 38
okano 19:7a7381e78025 39
okano 19:7a7381e78025 40
okano 19:7a7381e78025 41
okano 1:54e619428ae6 42 #define SOURCE_FILE "/local/bin"
okano 18:b401da200216 43
okano 18:b401da200216 44 // "ISP_BAUD_RATE" is baud rate for ISP operation
okano 18:b401da200216 45
okano 16:cac2348cfcfb 46 #define ISP_BAUD_RATE 115200
okano 16:cac2348cfcfb 47 //#define ISP_BAUD_RATE 57600
okano 16:cac2348cfcfb 48 //#define ISP_BAUD_RATE 9600
okano 16:cac2348cfcfb 49
okano 18:b401da200216 50 // "TARGET_OPERATION_BAUD_RATE" is baud rate for USB-serial bridge operation after
okano 18:b401da200216 51 // ISP completion.
okano 18:b401da200216 52 // if the target application uses serial(UART) and you use the bridge feature,
okano 18:b401da200216 53 // please set this value correctly.
okano 18:b401da200216 54
okano 16:cac2348cfcfb 55 #define TARGET_OPERATION_BAUD_RATE 9600
okano 4:55f1977bd11a 56
okano 8:b220fadbb3d8 57 int error_state = 0;
okano 7:815366f003ee 58
okano 20:98d7b5878e3e 59 int verify_flash( FILE *fp, target_param *tpp );
okano 20:98d7b5878e3e 60 int post_writing_process( target_param *tpp );
okano 20:98d7b5878e3e 61
okano 7:815366f003ee 62 int file_size( FILE *fp );
okano 7:815366f003ee 63 char read_byte( void );
okano 7:815366f003ee 64 void erase_sectors( int last_sector );
okano 19:7a7381e78025 65 int verify_binary_data( FILE *fp );
okano 20:98d7b5878e3e 66 int verify_uucoded_data( FILE *fp );
okano 20:98d7b5878e3e 67 void get_binary_from_uucode_str( char *b, int size );
okano 21:e149d0bdbf4a 68
okano 16:cac2348cfcfb 69 void success_indicator();
okano 7:815366f003ee 70
okano 19:7a7381e78025 71
okano 12:5a33b5d39792 72 #pragma diag_suppress 1293 // surpressing a warning message of "assignment in condition" ;)
okano 12:5a33b5d39792 73
okano 7:815366f003ee 74 int main()
okano 7:815366f003ee 75 {
okano 7:815366f003ee 76 FILE *fp;
okano 20:98d7b5878e3e 77 target_param *tpp;
okano 7:815366f003ee 78 int data_size;
okano 7:815366f003ee 79 int last_sector;
okano 8:b220fadbb3d8 80
okano 7:815366f003ee 81 printf( "\r\n\r\n\r\nmbed ISP program : programming LPC device from mbed\r\n" );
okano 7:815366f003ee 82
okano 20:98d7b5878e3e 83 if ( NULL == (tpp = open_target( ISP_BAUD_RATE )) )
okano 20:98d7b5878e3e 84 {
okano 20:98d7b5878e3e 85 error( "couldn't open the taget" );
okano 20:98d7b5878e3e 86 return ( 1 );
okano 20:98d7b5878e3e 87 }
okano 8:b220fadbb3d8 88
okano 8:b220fadbb3d8 89 printf( " target device found : type = \"%s\"\r\n", tpp->type_name );
okano 8:b220fadbb3d8 90 printf( " ID = 0x%08X\r\n", tpp->id );
okano 8:b220fadbb3d8 91 printf( " RAM size = %10d bytes\r\n", tpp->ram_size );
okano 8:b220fadbb3d8 92 printf( " flash size = %10d bytes\r\n", tpp->flash_size );
okano 8:b220fadbb3d8 93
okano 12:5a33b5d39792 94 printf( " opening file: \"%s\"\r\n", SOURCE_FILE );
okano 12:5a33b5d39792 95
okano 12:5a33b5d39792 96 if ( NULL == (fp = fopen( SOURCE_FILE, "rb" )) ) {
okano 12:5a33b5d39792 97 error( "couldn't open source file" );
okano 12:5a33b5d39792 98 return ( 1 );
okano 12:5a33b5d39792 99 }
okano 12:5a33b5d39792 100
okano 12:5a33b5d39792 101 data_size = file_size( fp );
okano 12:5a33b5d39792 102 last_sector = data_size / tpp->sector_size;
okano 12:5a33b5d39792 103
okano 12:5a33b5d39792 104 printf( " data size = %d bytes, it takes %d secotrs in flash area\r\n", data_size, last_sector + 1 );
okano 12:5a33b5d39792 105 printf( " resetting target\r\n" );
okano 12:5a33b5d39792 106
okano 7:815366f003ee 107 erase_sectors( last_sector );
okano 12:5a33b5d39792 108
okano 20:98d7b5878e3e 109 write_flash( fp, tpp );
okano 20:98d7b5878e3e 110 verify_flash( fp, tpp );
okano 12:5a33b5d39792 111
okano 7:815366f003ee 112 fclose( fp );
okano 8:b220fadbb3d8 113
okano 8:b220fadbb3d8 114 printf( "\r\n %s\r\n\r\n",
okano 8:b220fadbb3d8 115 error_state ?
okano 8:b220fadbb3d8 116 "** The data could not be written :(" :
okano 8:b220fadbb3d8 117 "** The data has been written successflly :)"
okano 8:b220fadbb3d8 118 );
okano 19:7a7381e78025 119
okano 19:7a7381e78025 120 if ( error_state )
okano 19:7a7381e78025 121 error( " ** ISP failed\r\n" );
okano 20:98d7b5878e3e 122
okano 20:98d7b5878e3e 123 post_writing_process( tpp );
okano 20:98d7b5878e3e 124
okano 8:b220fadbb3d8 125
okano 16:cac2348cfcfb 126 #define AUTO_PROGRAM_START
okano 14:a7b9f74fb856 127 #ifdef AUTO_PROGRAM_START
okano 21:e149d0bdbf4a 128 set_target_baud_rate( TARGET_OPERATION_BAUD_RATE );
okano 16:cac2348cfcfb 129
okano 14:a7b9f74fb856 130 reset_target( NO_ISP_MODE );
okano 16:cac2348cfcfb 131 printf( " ** The program in flash has been started!!\r\n" );
okano 14:a7b9f74fb856 132 #endif
okano 14:a7b9f74fb856 133
okano 16:cac2348cfcfb 134 printf( " (now the mbed is working in \"serial through mode\")\r\n\r\n" );
okano 16:cac2348cfcfb 135
okano 16:cac2348cfcfb 136 success.attach( &success_indicator, 0.1 );
okano 16:cac2348cfcfb 137
okano 21:e149d0bdbf4a 138 usb_serial_bridge_operation(); // doesn't return. infinite loop in this function
okano 20:98d7b5878e3e 139 }
okano 16:cac2348cfcfb 140
okano 20:98d7b5878e3e 141
okano 22:bd98a782fba6 142 int verify_flash( FILE *fp, target_param *tpp )
okano 22:bd98a782fba6 143 {
okano 22:bd98a782fba6 144 if ( tpp->write_type == BINARY )
okano 22:bd98a782fba6 145 verify_binary_data( fp );
okano 22:bd98a782fba6 146 else
okano 22:bd98a782fba6 147 verify_uucoded_data( fp );
okano 22:bd98a782fba6 148 }
okano 22:bd98a782fba6 149
okano 22:bd98a782fba6 150
okano 22:bd98a782fba6 151 int post_writing_process( target_param *tpp )
okano 22:bd98a782fba6 152 {
okano 22:bd98a782fba6 153 if ( tpp->write_type == UUENCODE )
okano 22:bd98a782fba6 154 try_and_check( "G 0 T\r\n", "0", 0 );
okano 22:bd98a782fba6 155
okano 22:bd98a782fba6 156 }
okano 22:bd98a782fba6 157
okano 22:bd98a782fba6 158
okano 22:bd98a782fba6 159 int file_size( FILE *fp )
okano 22:bd98a782fba6 160 {
okano 22:bd98a782fba6 161 int size;
okano 22:bd98a782fba6 162
okano 22:bd98a782fba6 163 fseek( fp, 0, SEEK_END ); // seek to end of file
okano 22:bd98a782fba6 164 size = ftell( fp ); // get current file pointer
okano 22:bd98a782fba6 165 fseek( fp, 0, SEEK_SET ); // seek back to beginning of file
okano 22:bd98a782fba6 166
okano 22:bd98a782fba6 167 return size;
okano 22:bd98a782fba6 168 }
okano 22:bd98a782fba6 169
okano 22:bd98a782fba6 170
okano 7:815366f003ee 171
okano 7:815366f003ee 172
okano 7:815366f003ee 173 void erase_sectors( int last_sector )
okano 7:815366f003ee 174 {
okano 7:815366f003ee 175 char command_str[ STR_BUFF_SIZE ];
okano 8:b220fadbb3d8 176
okano 7:815366f003ee 177 sprintf( command_str, "P 0 %d\r\n", last_sector );
okano 7:815366f003ee 178 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 179
okano 7:815366f003ee 180 *(command_str) = 'E';
okano 7:815366f003ee 181 try_and_check( command_str, "0", 0 );
okano 7:815366f003ee 182 }
okano 7:815366f003ee 183
okano 19:7a7381e78025 184
okano 19:7a7381e78025 185 int verify_binary_data( FILE *fp )
okano 19:7a7381e78025 186 {
okano 19:7a7381e78025 187 char command_str[ STR_BUFF_SIZE ];
okano 19:7a7381e78025 188 int read_size = 0;
okano 19:7a7381e78025 189 int size;
okano 19:7a7381e78025 190 int flash_reading_size;
okano 19:7a7381e78025 191 char *bf;
okano 19:7a7381e78025 192 char *br;
okano 19:7a7381e78025 193 int error_flag = 0;
okano 19:7a7381e78025 194 unsigned long checksum = 0;
okano 19:7a7381e78025 195 unsigned long checksum_count = 0;
okano 19:7a7381e78025 196
okano 19:7a7381e78025 197 fseek( fp, 0, SEEK_SET ); // seek back to beginning of file
okano 19:7a7381e78025 198
okano 19:7a7381e78025 199 flash_reading_size = 128;
okano 19:7a7381e78025 200
okano 19:7a7381e78025 201 if ( NULL == (bf = (char *)malloc( flash_reading_size * sizeof( char ) )) )
okano 19:7a7381e78025 202 error( "malloc error happened (in verify process, file data buffer)\r\n" );
okano 19:7a7381e78025 203
okano 19:7a7381e78025 204 if ( NULL == (br = (char *)malloc( flash_reading_size * sizeof( char ) )) )
okano 19:7a7381e78025 205 error( "malloc error happened (in verify process, read data buffer)\r\n" );
okano 19:7a7381e78025 206
okano 19:7a7381e78025 207
okano 19:7a7381e78025 208 printf( "\r\n ==== flash reading and verifying ====\r\n" );
okano 19:7a7381e78025 209
okano 19:7a7381e78025 210 while ( size = fread( bf, sizeof( char ), flash_reading_size, fp ) ) {
okano 19:7a7381e78025 211
okano 19:7a7381e78025 212 if ( read_size < 0x20 ) {
okano 19:7a7381e78025 213 for ( int i = 0; i < flash_reading_size; i += 4 ) {
okano 19:7a7381e78025 214
okano 19:7a7381e78025 215 if ( checksum_count == 7 ) {
okano 19:7a7381e78025 216 checksum = 0xFFFFFFFF - checksum + 1;
okano 19:7a7381e78025 217 *((unsigned int *)(bf + i)) = checksum;
okano 19:7a7381e78025 218 //printf( "\r\n\r\n -- calculated checksum : 0x%08X\r\n", checksum );
okano 19:7a7381e78025 219 } else {
okano 19:7a7381e78025 220 checksum += *((unsigned int *)(bf + i));
okano 19:7a7381e78025 221 }
okano 19:7a7381e78025 222
okano 19:7a7381e78025 223 checksum_count++;
okano 19:7a7381e78025 224 }
okano 19:7a7381e78025 225 }
okano 19:7a7381e78025 226
okano 19:7a7381e78025 227
okano 19:7a7381e78025 228 sprintf( command_str, "R %ld %ld\r\n", read_size, size );
okano 19:7a7381e78025 229 // try_and_check( command_str, "0", MODE_SILENT );
okano 19:7a7381e78025 230 try_and_check( command_str, "0", 0 );
okano 19:7a7381e78025 231
okano 19:7a7381e78025 232 get_binary( br, 1 );
okano 19:7a7381e78025 233 get_binary( br, size );
okano 19:7a7381e78025 234
okano 19:7a7381e78025 235 for ( int i = 0; i < size; i++ ) {
okano 19:7a7381e78025 236 // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) );
okano 19:7a7381e78025 237 if ( (*(bf + i) != *(br + i)) ) {
okano 19:7a7381e78025 238 // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) );
okano 19:7a7381e78025 239 error_flag++;
okano 19:7a7381e78025 240 }
okano 19:7a7381e78025 241 }
okano 19:7a7381e78025 242
okano 19:7a7381e78025 243 if ( error_flag )
okano 19:7a7381e78025 244 break;
okano 19:7a7381e78025 245
okano 19:7a7381e78025 246 read_size += size;
okano 19:7a7381e78025 247
okano 19:7a7381e78025 248 // printf( " total %d bytes read\r\n", read_size );
okano 19:7a7381e78025 249 }
okano 19:7a7381e78025 250
okano 19:7a7381e78025 251 error_state |= error_flag;
okano 19:7a7381e78025 252
okano 19:7a7381e78025 253 printf( " total %d bytes read\r", read_size );
okano 19:7a7381e78025 254 printf( " verification result : \"%s\"\r\n", error_flag ? "Fail" : "Pass" );
okano 19:7a7381e78025 255
okano 19:7a7381e78025 256 free( bf );
okano 19:7a7381e78025 257 free( br );
okano 19:7a7381e78025 258
okano 19:7a7381e78025 259 return ( read_size );
okano 19:7a7381e78025 260 }
okano 19:7a7381e78025 261
okano 19:7a7381e78025 262
okano 20:98d7b5878e3e 263 int verify_uucoded_data( FILE *fp )
okano 20:98d7b5878e3e 264 {
okano 20:98d7b5878e3e 265 char command_str[ STR_BUFF_SIZE ];
okano 20:98d7b5878e3e 266 int read_size = 0;
okano 20:98d7b5878e3e 267 int size;
okano 20:98d7b5878e3e 268 int flash_reading_size;
okano 20:98d7b5878e3e 269 char *bf;
okano 20:98d7b5878e3e 270 char *br;
okano 20:98d7b5878e3e 271 int error_flag = 0;
okano 20:98d7b5878e3e 272
okano 20:98d7b5878e3e 273 flash_reading_size = 176;
okano 20:98d7b5878e3e 274
okano 22:bd98a782fba6 275 initialize_uud_table();
okano 22:bd98a782fba6 276
okano 20:98d7b5878e3e 277 if ( NULL == (bf = (char *)malloc( flash_reading_size * sizeof( char ) )) )
okano 20:98d7b5878e3e 278 error( "malloc error happened (in verify process, file data buffer)\r\n" );
okano 20:98d7b5878e3e 279
okano 20:98d7b5878e3e 280 if ( NULL == (br = (char *)malloc( flash_reading_size * sizeof( char ) )) )
okano 20:98d7b5878e3e 281 error( "malloc error happened (in verify process, read data buffer)\r\n" );
okano 20:98d7b5878e3e 282
okano 20:98d7b5878e3e 283 fseek( fp, 0, SEEK_SET ); // seek back to beginning of file
okano 20:98d7b5878e3e 284
okano 20:98d7b5878e3e 285 while ( size = fread( bf, sizeof( char ), flash_reading_size, fp ) ) {
okano 20:98d7b5878e3e 286
okano 20:98d7b5878e3e 287 if ( !read_size ) {
okano 20:98d7b5878e3e 288 // overwriting 4 bytes data for address=0x1C
okano 20:98d7b5878e3e 289 // there is a slot for checksum that is checked in (target's) boot process
okano 20:98d7b5878e3e 290 add_isp_checksum( bf );
okano 20:98d7b5878e3e 291 }
okano 20:98d7b5878e3e 292
okano 20:98d7b5878e3e 293 sprintf( command_str, "R %ld %ld\r\n", read_size, size );
okano 20:98d7b5878e3e 294 try_and_check( command_str, "0", 0 );
okano 20:98d7b5878e3e 295
okano 20:98d7b5878e3e 296 get_binary_from_uucode_str( br, size );
okano 20:98d7b5878e3e 297
okano 20:98d7b5878e3e 298 for ( int i = 0; i < size; i++ ) {
okano 20:98d7b5878e3e 299 // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) );
okano 20:98d7b5878e3e 300 if ( (*(bf + i) != *(br + i)) ) {
okano 20:98d7b5878e3e 301 printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) );
okano 20:98d7b5878e3e 302 error_flag++;
okano 20:98d7b5878e3e 303 }
okano 20:98d7b5878e3e 304 }
okano 20:98d7b5878e3e 305
okano 20:98d7b5878e3e 306 if ( error_flag )
okano 20:98d7b5878e3e 307 break;
okano 20:98d7b5878e3e 308
okano 20:98d7b5878e3e 309 read_size += size;
okano 20:98d7b5878e3e 310 // printf( " total %d bytes read\r", read_size );
okano 20:98d7b5878e3e 311 }
okano 20:98d7b5878e3e 312
okano 20:98d7b5878e3e 313 error_state |= error_flag;
okano 20:98d7b5878e3e 314
okano 20:98d7b5878e3e 315 printf( " total %d bytes read\r", read_size );
okano 20:98d7b5878e3e 316 printf( " verification result : \"%s\"\r\n", error_flag ? "Fail" : "Pass" );
okano 20:98d7b5878e3e 317
okano 20:98d7b5878e3e 318 free( bf );
okano 20:98d7b5878e3e 319 free( br );
okano 20:98d7b5878e3e 320
okano 20:98d7b5878e3e 321 return ( read_size );
okano 20:98d7b5878e3e 322 }
okano 20:98d7b5878e3e 323
okano 20:98d7b5878e3e 324
okano 20:98d7b5878e3e 325 void get_binary_from_uucode_str( char *b, int size )
okano 20:98d7b5878e3e 326 {
okano 20:98d7b5878e3e 327 #define N 4
okano 20:98d7b5878e3e 328
okano 20:98d7b5878e3e 329 char s[ N ][ STR_BUFF_SIZE ];
okano 20:98d7b5878e3e 330 char ss[ STR_BUFF_SIZE ];
okano 20:98d7b5878e3e 331 long checksum = 0;
okano 20:98d7b5878e3e 332 int line_count = 0;
okano 20:98d7b5878e3e 333 int read_size = 0;
okano 20:98d7b5878e3e 334 int retry_count = 3;
okano 20:98d7b5878e3e 335
okano 20:98d7b5878e3e 336
okano 20:98d7b5878e3e 337 while ( retry_count-- ) {
okano 20:98d7b5878e3e 338
okano 20:98d7b5878e3e 339 for ( int i = 0; i < N; i++ )
okano 20:98d7b5878e3e 340 get_string( s[ i ] );
okano 20:98d7b5878e3e 341
okano 20:98d7b5878e3e 342 get_string( ss );
okano 20:98d7b5878e3e 343
okano 20:98d7b5878e3e 344
okano 20:98d7b5878e3e 345 while ( size ) {
okano 20:98d7b5878e3e 346 read_size = uudecode_a_line( b, s[ line_count ] );
okano 20:98d7b5878e3e 347
okano 20:98d7b5878e3e 348 for ( int i = 0; i < read_size; i++ )
okano 20:98d7b5878e3e 349 checksum += *b++;
okano 20:98d7b5878e3e 350
okano 20:98d7b5878e3e 351 size -= read_size;
okano 20:98d7b5878e3e 352 line_count++;
okano 20:98d7b5878e3e 353 }
okano 20:98d7b5878e3e 354
okano 20:98d7b5878e3e 355 // printf( " checksum -- %s (internal = %ld)\r\n", ss, checksum );
okano 20:98d7b5878e3e 356
okano 20:98d7b5878e3e 357 if ( checksum == atol( ss ) ) {
okano 20:98d7b5878e3e 358 put_string( "OK\r\n" );
okano 20:98d7b5878e3e 359 return;
okano 20:98d7b5878e3e 360 // printf( " checksum OK\r\n" );
okano 20:98d7b5878e3e 361 } else {
okano 20:98d7b5878e3e 362 printf( " checksum RESEND\r\n" );
okano 20:98d7b5878e3e 363 put_string( "RESEND\r\n" );
okano 20:98d7b5878e3e 364 }
okano 20:98d7b5878e3e 365 }
okano 20:98d7b5878e3e 366 }
okano 20:98d7b5878e3e 367
okano 20:98d7b5878e3e 368
okano 20:98d7b5878e3e 369
okano 4:55f1977bd11a 370
okano 0:6baefda2e511 371
okano 19:7a7381e78025 372
okano 16:cac2348cfcfb 373 void success_indicator()
okano 16:cac2348cfcfb 374 {
okano 16:cac2348cfcfb 375 static int i = 0;
okano 16:cac2348cfcfb 376
okano 16:cac2348cfcfb 377 leds = 0x1 << (i++ & 0x3);
okano 16:cac2348cfcfb 378 }
okano 21:e149d0bdbf4a 379
okano 21:e149d0bdbf4a 380
okano 21:e149d0bdbf4a 381 void set_leds( char v )
okano 21:e149d0bdbf4a 382 {
okano 21:e149d0bdbf4a 383 leds = v;
okano 21:e149d0bdbf4a 384 }