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:
Sat Aug 24 13:08:37 2013 +0000
Revision:
1:54e619428ae6
Parent:
0:6baefda2e511
Child:
2:8d75eb0ecd20
ISP checksum addition

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okano 0:6baefda2e511 1 #include "mbed.h"
okano 0:6baefda2e511 2
okano 0:6baefda2e511 3 DigitalOut led1(LED1);
okano 0:6baefda2e511 4 DigitalOut led2(LED2);
okano 0:6baefda2e511 5
okano 0:6baefda2e511 6 DigitalOut reset_pin( p26 );
okano 0:6baefda2e511 7 DigitalOut isp_pin( p25 );
okano 0:6baefda2e511 8
okano 0:6baefda2e511 9 Serial pc (USBTX,USBRX);
okano 0:6baefda2e511 10 Serial target (p28,p27);
okano 0:6baefda2e511 11
okano 0:6baefda2e511 12 LocalFileSystem local("local");
okano 0:6baefda2e511 13
okano 1:54e619428ae6 14 #define SOURCE_FILE "/local/bin"
okano 1:54e619428ae6 15 #define STR_BUFF_SIZE 64
okano 1:54e619428ae6 16 #define RAM_START_ADDRESS 0x10000300L
okano 1:54e619428ae6 17 #define SECTOR_SIZE 4096
okano 0:6baefda2e511 18
okano 0:6baefda2e511 19 void put_string( char *s );
okano 0:6baefda2e511 20 void get_string( char *s );
okano 0:6baefda2e511 21
okano 0:6baefda2e511 22
okano 0:6baefda2e511 23 int try_and_check( char *command, char *expected_return_str, int mode )
okano 0:6baefda2e511 24 {
okano 0:6baefda2e511 25 char rtn_str[ STR_BUFF_SIZE ];
okano 0:6baefda2e511 26
okano 0:6baefda2e511 27 put_string( command );
okano 0:6baefda2e511 28 get_string( rtn_str );
okano 0:6baefda2e511 29
okano 0:6baefda2e511 30 return ( strcmp( expected_return_str, rtn_str ) );
okano 0:6baefda2e511 31 }
okano 0:6baefda2e511 32
okano 0:6baefda2e511 33 int try_and_check2( char *command, char *expected_return_str, int mode )
okano 0:6baefda2e511 34 {
okano 0:6baefda2e511 35 char rtn_str[ STR_BUFF_SIZE ];
okano 0:6baefda2e511 36
okano 0:6baefda2e511 37 put_string( command );
okano 0:6baefda2e511 38
okano 0:6baefda2e511 39 get_string( rtn_str ); // just readout echoback
okano 0:6baefda2e511 40 get_string( rtn_str );
okano 0:6baefda2e511 41
okano 0:6baefda2e511 42 return ( strcmp( expected_return_str, rtn_str ) );
okano 0:6baefda2e511 43 }
okano 0:6baefda2e511 44
okano 0:6baefda2e511 45 char read_byte( void )
okano 0:6baefda2e511 46 {
okano 0:6baefda2e511 47 while ( !target.readable() )
okano 0:6baefda2e511 48 ;
okano 0:6baefda2e511 49
okano 0:6baefda2e511 50 return ( target.getc() );
okano 0:6baefda2e511 51 }
okano 0:6baefda2e511 52 char uue_table[ 64 ];
okano 0:6baefda2e511 53
okano 0:6baefda2e511 54 void initialize_uue_table( void )
okano 0:6baefda2e511 55 {
okano 0:6baefda2e511 56 int i;
okano 0:6baefda2e511 57
okano 0:6baefda2e511 58 uue_table[0] = 0x60; // 0x20 is translated to 0x60 !
okano 0:6baefda2e511 59
okano 0:6baefda2e511 60 for (i = 1; i < 64; i++) {
okano 0:6baefda2e511 61 uue_table[i] = (char)(0x20 + i);
okano 0:6baefda2e511 62 }
okano 0:6baefda2e511 63 }
okano 0:6baefda2e511 64
okano 0:6baefda2e511 65 long bin2uue( char *bin, char *str )
okano 0:6baefda2e511 66 {
okano 0:6baefda2e511 67 unsigned long v;
okano 1:54e619428ae6 68 long checksum = 0;
okano 0:6baefda2e511 69 int strpos = 0;
okano 0:6baefda2e511 70
okano 0:6baefda2e511 71 *(str + strpos++) = ' ' + 45;
okano 0:6baefda2e511 72
okano 0:6baefda2e511 73 for ( int i = 0; i < 45; i += 3 ) {
okano 1:54e619428ae6 74 checksum += *(bin + i + 0) + *(bin + i + 1) + *(bin + i + 2);
okano 0:6baefda2e511 75 v = (*(bin + i + 0) << 16) | (*(bin + i + 1) << 8) | (*(bin + i + 2) << 0);
okano 0:6baefda2e511 76 *(str + strpos++) = uue_table[ (v >> 18) & 0x3F ];
okano 0:6baefda2e511 77 *(str + strpos++) = uue_table[ (v >> 12) & 0x3F ];
okano 0:6baefda2e511 78 *(str + strpos++) = uue_table[ (v >> 6) & 0x3F ];
okano 0:6baefda2e511 79 *(str + strpos++) = uue_table[ (v >> 0) & 0x3F ];
okano 0:6baefda2e511 80 }
okano 0:6baefda2e511 81 *(str + strpos++) = '\n';
okano 0:6baefda2e511 82 *(str + strpos++) = '\0';
okano 0:6baefda2e511 83
okano 1:54e619428ae6 84 return checksum;
okano 0:6baefda2e511 85 }
okano 0:6baefda2e511 86
okano 1:54e619428ae6 87 void add_isp_checksum( char *b )
okano 1:54e619428ae6 88 {
okano 1:54e619428ae6 89 // see http://www.lpcware.com/content/nxpfile/lpc177x8x-checksum-insertion-program
okano 1:54e619428ae6 90
okano 1:54e619428ae6 91 unsigned int *p;
okano 1:54e619428ae6 92 unsigned int cksum = 0;
okano 1:54e619428ae6 93
okano 1:54e619428ae6 94 p = (unsigned int *)b;
okano 1:54e619428ae6 95
okano 1:54e619428ae6 96 for ( int i = 0; i < 7; i++ ) {
okano 1:54e619428ae6 97 cksum += *p++;
okano 1:54e619428ae6 98 }
okano 1:54e619428ae6 99
okano 1:54e619428ae6 100 printf( " -- value at checksum slot : 0x%08X\r\n", *p );
okano 1:54e619428ae6 101
okano 1:54e619428ae6 102 *p = 0xFFFFFFFF - cksum + 1;
okano 1:54e619428ae6 103 printf( " -- calculated checksum : 0x%08X\r\n", *p );
okano 1:54e619428ae6 104
okano 1:54e619428ae6 105 printf( " new checksum will be used to program flash\r\n" );
okano 1:54e619428ae6 106 }
okano 1:54e619428ae6 107
okano 1:54e619428ae6 108
okano 1:54e619428ae6 109
okano 1:54e619428ae6 110 void erase_sectors( int last_sector )
okano 1:54e619428ae6 111 {
okano 1:54e619428ae6 112 char command_str[ STR_BUFF_SIZE ];
okano 1:54e619428ae6 113
okano 1:54e619428ae6 114 sprintf( command_str, "P 0 %d\r\n", last_sector );
okano 1:54e619428ae6 115
okano 1:54e619428ae6 116 printf( "\"%s\" %s\r\n", command_str, try_and_check( command_str, "0", 0 ) ? "Fail" : "Pass" );
okano 1:54e619428ae6 117
okano 1:54e619428ae6 118 *(command_str) = 'E';
okano 1:54e619428ae6 119 printf( "\"%s\" %s\r\n", command_str, try_and_check( command_str, "0", 0 ) ? "Fail" : "Pass" );
okano 1:54e619428ae6 120 }
okano 0:6baefda2e511 121
okano 0:6baefda2e511 122 #define FLASH_WRITING_SIZE 1024
okano 0:6baefda2e511 123 #define TRANSFER_SIZE (24 * 45)
okano 0:6baefda2e511 124
okano 0:6baefda2e511 125 char b[ TRANSFER_SIZE ];
okano 0:6baefda2e511 126
okano 1:54e619428ae6 127 void write_binary_data( FILE *fp )
okano 0:6baefda2e511 128 {
okano 0:6baefda2e511 129 char command_str[ STR_BUFF_SIZE ];
okano 1:54e619428ae6 130 long checksum = 0;
okano 0:6baefda2e511 131 int transfer_count = 0;
okano 0:6baefda2e511 132 int size;
okano 0:6baefda2e511 133
okano 0:6baefda2e511 134 initialize_uue_table();
okano 0:6baefda2e511 135
okano 0:6baefda2e511 136 for ( int i = FLASH_WRITING_SIZE; i < TRANSFER_SIZE; i++ )
okano 0:6baefda2e511 137 b[ i ] = 0;
okano 0:6baefda2e511 138
okano 0:6baefda2e511 139 while ( size = fread( b, sizeof( char ), FLASH_WRITING_SIZE, fp ) ) {
okano 0:6baefda2e511 140
okano 1:54e619428ae6 141 if ( !transfer_count ) {
okano 1:54e619428ae6 142 add_isp_checksum( b );
okano 1:54e619428ae6 143 }
okano 1:54e619428ae6 144
okano 1:54e619428ae6 145 sprintf( command_str, "W %ld %ld\r\n", RAM_START_ADDRESS, 1080 );
okano 0:6baefda2e511 146 printf( "\"%s\" %s\r\n", command_str, try_and_check( command_str, "0", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 147
okano 0:6baefda2e511 148 for ( int i = 0; i < 24; i++ ) {
okano 1:54e619428ae6 149 checksum += bin2uue( b + (i * 45), command_str );
okano 0:6baefda2e511 150 printf( "%02d %s\r\n", i, command_str );
okano 0:6baefda2e511 151 put_string( command_str );
okano 0:6baefda2e511 152 if ( (i == 19) || (i == 23) ) {
okano 1:54e619428ae6 153 sprintf( command_str, "%ld\n", checksum );
okano 1:54e619428ae6 154 printf( " %ld %s\r\n", checksum, command_str );
okano 0:6baefda2e511 155 printf( "\"%s\" %s\r\n", command_str, try_and_check( command_str, "OK", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 156
okano 1:54e619428ae6 157 checksum = 0;
okano 0:6baefda2e511 158 }
okano 0:6baefda2e511 159 }
okano 0:6baefda2e511 160
okano 0:6baefda2e511 161 printf( "\"P 0 0\" %s\r\n", try_and_check( "P 0 0\r\n", "0", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 162
okano 0:6baefda2e511 163 sprintf( command_str, "C %ld %ld %ld\r\n", FLASH_WRITING_SIZE * transfer_count++, 0x10000300L, FLASH_WRITING_SIZE );
okano 0:6baefda2e511 164 printf( "\"%s\" %s\r\n", command_str, try_and_check( command_str, "0", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 165
okano 0:6baefda2e511 166
okano 0:6baefda2e511 167 }
okano 0:6baefda2e511 168 printf( "\"G 0 T\" %s\r\n", try_and_check( "G 0 T\r\n", "0", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 169 }
okano 0:6baefda2e511 170
okano 1:54e619428ae6 171 int file_size( FILE *fp )
okano 1:54e619428ae6 172 {
okano 1:54e619428ae6 173 int size;
okano 1:54e619428ae6 174
okano 1:54e619428ae6 175 fseek( fp, 0, SEEK_END ); // seek to end of file
okano 1:54e619428ae6 176 size = ftell( fp ); // get current file pointer
okano 1:54e619428ae6 177 fseek( fp, 0, SEEK_SET ); // seek back to beginning of file
okano 1:54e619428ae6 178
okano 1:54e619428ae6 179 return size;
okano 1:54e619428ae6 180 }
okano 1:54e619428ae6 181
okano 1:54e619428ae6 182 void reset_target( int isp_pin_state )
okano 1:54e619428ae6 183 {
okano 1:54e619428ae6 184 reset_pin = 1;
okano 1:54e619428ae6 185 isp_pin = 0;
okano 1:54e619428ae6 186 wait_ms( 100 );
okano 1:54e619428ae6 187 reset_pin = 0;
okano 1:54e619428ae6 188 wait_ms( 100 );
okano 1:54e619428ae6 189 reset_pin = 1;
okano 1:54e619428ae6 190 wait_ms( 100 );
okano 1:54e619428ae6 191 }
okano 1:54e619428ae6 192
okano 0:6baefda2e511 193 int main()
okano 0:6baefda2e511 194 {
okano 0:6baefda2e511 195 FILE *fp;
okano 0:6baefda2e511 196 char str_buf0[ STR_BUFF_SIZE ];
okano 0:6baefda2e511 197 char str_buf1[ STR_BUFF_SIZE ];
okano 1:54e619428ae6 198 int data_size;
okano 1:54e619428ae6 199 int last_sector;
okano 0:6baefda2e511 200
okano 0:6baefda2e511 201 pc.baud(9600);
okano 0:6baefda2e511 202 target.baud(9600);
okano 0:6baefda2e511 203
okano 0:6baefda2e511 204 if ( NULL == (fp = fopen( SOURCE_FILE, "rb" )) ) {
okano 0:6baefda2e511 205 error( "couldn't open source file" );
okano 0:6baefda2e511 206 return ( 1 );
okano 0:6baefda2e511 207 }
okano 0:6baefda2e511 208
okano 1:54e619428ae6 209 data_size = file_size( fp );
okano 1:54e619428ae6 210 last_sector = data_size / SECTOR_SIZE;
okano 0:6baefda2e511 211 printf( "\r\n\r\ntarget RESET\r\n" );
okano 1:54e619428ae6 212 printf( "data size = %d bytes, it takes %d secotrs in flash area\r\n", data_size, last_sector + 1 );
okano 0:6baefda2e511 213
okano 1:54e619428ae6 214 reset_target( 0 );
okano 0:6baefda2e511 215
okano 0:6baefda2e511 216 printf( "\"?\" >> \"Synchronized\" %s\r\n", try_and_check( "?", "Synchronized", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 217 printf( "\"Synchronized\\r\\n\" %s\r\n", try_and_check2( "Synchronized\r\n", "OK", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 218 printf( "\"12000\" %s\r\n", try_and_check2( "12000\r\n", "OK", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 219 printf( "\"U 23130\" %s\r\n", try_and_check2( "U 23130\r\n", "0", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 220 printf( "\"A 0\" %s\r\n", try_and_check2( "A 0\r\n", "0", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 221
okano 0:6baefda2e511 222 printf( "\"K\" %s\r\n", try_and_check( "K\r\n", "0", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 223 get_string( str_buf0 );
okano 0:6baefda2e511 224 get_string( str_buf1 );
okano 0:6baefda2e511 225 printf( " result of \"K\" = %s %s\r\n", str_buf0, str_buf1 );
okano 0:6baefda2e511 226
okano 0:6baefda2e511 227 printf( "\"J\" %s\r\n", try_and_check( "J\r\n", "0", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 228 get_string( str_buf0 );
okano 0:6baefda2e511 229 printf( " result of \"J\" = %s\r\n", str_buf0 );
okano 0:6baefda2e511 230
okano 0:6baefda2e511 231 #if 0
okano 0:6baefda2e511 232 printf( "\"N\" %s\r\n", try_and_check( "N\r\n", "0", 0 ) ? "Fail" : "Pass" );
okano 0:6baefda2e511 233 get_string( str_buf0 );
okano 0:6baefda2e511 234 printf( " result of \"N\" = %s %lX\r\n", str_buf0, atol( str_buf0 ) );
okano 0:6baefda2e511 235 get_string( str_buf0 );
okano 0:6baefda2e511 236 printf( " result of \"N\" = %s %lX\r\n", str_buf0, atol( str_buf0 ) );
okano 0:6baefda2e511 237 get_string( str_buf0 );
okano 0:6baefda2e511 238 printf( " result of \"N\" = %s %lX\r\n", str_buf0, atol( str_buf0 ) );
okano 0:6baefda2e511 239 get_string( str_buf0 );
okano 0:6baefda2e511 240 printf( " result of \"N\" = %s %lX\r\n", str_buf0, atol( str_buf0 ) );
okano 0:6baefda2e511 241 #endif
okano 0:6baefda2e511 242
okano 1:54e619428ae6 243 erase_sectors( last_sector );
okano 1:54e619428ae6 244
okano 1:54e619428ae6 245 write_binary_data( fp );
okano 0:6baefda2e511 246 fclose( fp );
okano 0:6baefda2e511 247
okano 0:6baefda2e511 248 while ( 1 )
okano 0:6baefda2e511 249 ;
okano 0:6baefda2e511 250 }
okano 0:6baefda2e511 251
okano 0:6baefda2e511 252 void put_string( char *s )
okano 0:6baefda2e511 253 {
okano 0:6baefda2e511 254 char c;
okano 0:6baefda2e511 255
okano 0:6baefda2e511 256 while ( (c = *s++) )
okano 0:6baefda2e511 257 target.putc( c );
okano 0:6baefda2e511 258 }
okano 0:6baefda2e511 259
okano 0:6baefda2e511 260 void get_string( char *s )
okano 0:6baefda2e511 261 {
okano 0:6baefda2e511 262 int i = 0;
okano 0:6baefda2e511 263 char c = 0;
okano 0:6baefda2e511 264
okano 0:6baefda2e511 265 do {
okano 0:6baefda2e511 266 do {
okano 0:6baefda2e511 267 if ( target.readable() ) {
okano 0:6baefda2e511 268 c = target.getc();
okano 0:6baefda2e511 269
okano 0:6baefda2e511 270 if ( ( c == '\n') || (c == '\r') )
okano 0:6baefda2e511 271 break;
okano 0:6baefda2e511 272
okano 0:6baefda2e511 273 *s++ = c;
okano 0:6baefda2e511 274 i++;
okano 0:6baefda2e511 275 led2 = !led2;
okano 0:6baefda2e511 276
okano 0:6baefda2e511 277 }
okano 0:6baefda2e511 278 } while ( 1 );
okano 0:6baefda2e511 279 } while ( !i );
okano 0:6baefda2e511 280 *s = '\0';
okano 0:6baefda2e511 281 }
okano 0:6baefda2e511 282