楽天市場
[無料でホームページを作成] [通報・削除依頼]

PIC16F18857をPICKIT2で焼く

前回PICKIT2でPIC16F18313に書き込む方法を記載しました。
今回はPICKIT2でPIC16F18857に書き込む方法を検討します。

最初に結論を言いますと、PICKIT2でflash/EEPROMともPIC16F18857に書き込むことは可能です。
条件としては、①ホスト側のPICkit2_PCAppSource_V2_61に最小限手を加え、再コンパイルする必要がある。
       ②14個の新しいスクリプトをpk2devicefile.datに加える必要がある。

2018.01.19追記 問題解決しました。
ただし、現状で1つ問題があります。PIC16F18857に書き込んだ後、PICKIT2を終了させ、PICKIT2を再度立ち上げて、
書き込んだPIC16F18857を読み出すと、flashメモリの内容が、(0x0000から0x5FFFの領域で)正しく読み出せない。


もし、このページを訪問された方で、何かお気づきの点がありましたら、お教えください。
(当方、Cのプログラムは不得手なため。)



<PIC16F18313とPIC16F18857のICSPコマンドの違いと相似点>

以下にPIC16F18313とPIC16F18857のICSPコマンドを比較します。(上段:PIC16F18313、下段:PIC16F18857)
img_20180115-201810.jpg
img_20180115-201834.jpg
PIC16F18857での相違点
①Load Configuration コマンドの廃止。
②全てのコマンド長さが6bitから8bitに変更。
③全てのコマンドのHEX値が変更。
④コマンド/ペイロードの入出力順がLSBファーストからMSBファーストに変更。
⑤全てのペイロードサイズが24bitに変更。

以下にPIC16F18313とPIC16F18857のLoad PC Adressコマンドを比較します。
(上段:PIC16F18313、下段:PIC16F18857)
img_20180115-203031.jpg
img_20180115-203120.jpg
この比較で特筆すべきは、アドレス長を22bitとみなすと、MSBファースト/LSBファーストの違いがあるものの、
ペイロードの形が "0"+アドレス本体+"0" となっていることです。

次にPIC16F18313とPIC16F18857のLoad for NVMコマンドを比較します。
(上段:PIC16F18313、下段:PIC16F18857)
img_20180115-202958.jpg
----------------------------------------------------------------------------------------------------------
img_20180115-203825.jpg

この比較でもやはり、ペイロード長、MSBファースト/LSBファーストの違いがあるものの、
ペイロードの形が "0"+データ本体+"0" となっています。

以上2点の相似点をうまく利用し、MSBファースト/LSBファーストの違いを考慮すれば、
PIC16F18857にも書き込み可能と考えました。以下pickit2で書き込む方法について考察します。


<PIC16F18313とPIC16F18857のICSPコマンドの相似点を利用した書き込み方法1>
○PIC16F18857のスクリプトをPIC16F18313のように記述、バッファーを2個使用。

①Load PC Adressコマンド
PIC16F18313のLoad PC Adressのスクリプトは以下のようでした。
AAEE    BB06    BB1D    AAF2    BB00    AAF2    BBE0    AAF2    BB01                            

EE 1D 06    WRITE_BITS_LITERAL    1D 06      //Load PC Address(1D)
F2 00         WRITE_BYTE_LITERAL    00          //Adress L         0xF000*2 = 0x01E000
F2 E0         WRITE_BYTE_LITERAL    E0          //Adress H
F2 01         WRITE_BYTE_LITERAL    01          //Adress U

現状のデータ転送方式(LSBファースト)を考慮して、PIC16F18857では以下のようにすればよいと思われます。
AAF2    BB01    AAE7    BB01    AAF2    BB80    AAF2    BB07    AAF2    BB00

F2 01    WRITE_BYTE_LITERAL    01    //0000.0001 -> 1000.0000    Load PC Address(80)
E7 01    DELAY_SHORT               01    //TDLYの時間を作る
F2 80    WRITE_BYTE_LITERAL    80    //1000.0000 -> 0000.0001    0x01          //Adress U
F2 07    WRITE_BYTE_LITERAL    07    //0000.0111 -> 1110.0000    0xE0          //Adress H
F2 00    WRITE_BYTE_LITERAL    00                                               0x00          //Adress L

②Load for NVMコマンド
PIC16F18313のLoad for NVMのスクリプトは以下のようでした。
AAEE    BB06    BB02    AAF1    AAF1

EE 02 06    WRITE_BITS_LITERAL    02 06     //Load for NVM(02)
F1              WRITE_BYTE_BUFFER                 //Data L
F1              WRITE_BYTE_BUFFER                 //Data H  

現状のデータ転送方式(LSBファースト)を考慮して、PIC16F18857では以下のようにすればよいと思われます。
AAF2    BB00    AAE7    BB01    AAF2    BB00    AAF1    AAF1

F2 00    WRITE_BYTE_LITERAL    00    //0000.0000 -> 0000.0000    Load for NVM(00)
E7 01    DELAY_SHORT               01    //TDLYの時間を作る
F2 00    WRITE_BYTE_LITERAL    00    //Data U  *0を書き込み
F1    WRITE_BYTE_BUFFER                 //Data L   *送信後にホスト内でH<-->L 入れ替え、LAB<-->MSB 並び替え
F1    WRITE_BYTE_BUFFER                 //Data H   *送信後にホスト内でH<-->L 入れ替え、LAB<-->MSB 並び替え   

③Read from NVMコマンド
PIC16F18313のLoad for NVMのスクリプトは以下のようでした。
AAEE    BB06    BB04    AAF0    AAF0

EE 04 06    WRITE_BITS_LITERAL    04 06    //Read from NVM(04)
F0    READ_BYTE_BUFFER                            //Data L  
F0    READ_BYTE_BUFFER                            //Data H 

現状のデータ転送方式(LSBファースト)を考慮して、PIC16F18857では以下のようにすればよいと思われます。
AAF2    BB3F    AAE7    BB01    AAEF    AAF0    AAF0

F2 3F    WRITE_BYTE_LITERAL    3F    //0011.1111 -> 1111.1100    Read from NVM(FC)
E7 01    DELAY_SHORT               01
EF    READ_BYTE                               //Data U  *空読み(バッファーにストアしない)          
F0    READ_BYTE_BUFFER                  //Data L   *受信前にホスト内でH<-->L 入れ替え、LAB<-->MSB 並び替え   
F0    READ_BYTE_BUFFER                  //Data H   *受信前にホスト内でH<-->L 入れ替え、LAB<-->MSB 並び替え     

④その他のコマンド
LAB<-->MSB のみ並び替え
F2 18    WRITE_BYTE_LITERAL    18    //0001.1000 -> 0001.1000    Bulk Erase Memory(18)
F2 0F    WRITE_BYTE_LITERAL    0F    //0000.1111 -> 1111.0000    Raw Erase Memory(F0)
F2 1F    WRITE_BYTE_LITERAL    1F    //0001.1111 -> 1111.1000    Increment Address(F8)
F2 07    WRITE_BYTE_LITERAL    07    //0000.0111 -> 1110.0000    Begin Program(E0)


<PIC16F18313とPIC16F18857のICSPコマンドの相似点を利用した書き込み方法2>
○ホスト側の変更例: バッファーの入れ替えとビットリバース

        public static void ReadConfigOutsideProgMem()
        {
            RunScript(KONST.PROG_ENTRY, 1);
            RunScript(KONST.CONFIG_RD, 1);
            UploadData();
            RunScript(KONST.PROG_EXIT, 1);
            int configWords = DevFile.PartsList[ActivePart].ConfigWords;
            int bufferIndex = 2;                    // report starts on index 1, which is #bytes uploaded.
            for (int word = 0; word < configWords; word++)
            {
                uint config = (uint)Usb_read_array[bufferIndex++];
                config |= (uint)Usb_read_array[bufferIndex++] << 8;
//$$$Bequest333
                if (DevFile.Families[GetActiveFamily()].FamilyName == "Midrange/1.8V Min MSB1st")
                {
                    config = reverse16Bits(config);
                }
//$$$

                if (DevFile.Families[GetActiveFamily()].ProgMemShift > 0)
                {
                    config = (config >> 1) & DevFile.Families[GetActiveFamily()].BlankValue;
                }
                DeviceBuffers.ConfigWords[word] = config;
            }        
        }
----------------------------------------------------------------------------------------------------------
                if (DevFile.Families[GetActiveFamily()].ProgMemShift > 0)
                { // baseline & midrange
                    configWord |= (~(uint)DevFile.PartsList[ActivePart].ConfigMasks[i] & ~DevFile.PartsList[ActivePart].BandGapMask);
                    if (!FamilyIsMCP())
                        configWord &= DevFile.Families[GetActiveFamily()].BlankValue;
                    configWord = configWord << 1;
                }
//$$$Bequest333
                if (DevFile.Families[GetActiveFamily()].FamilyName == "Midrange/1.8V Min MSB1st")
                {
                    configWord = reverse16Bits(configWord);
                }
//$$$

                configBuffer[j++] = (byte)(configWord & 0xFF);
                configBuffer[j++] = (byte)((configWord >> 8) & 0xFF);
                checksumPk2Go += (byte)(configWord & 0xFF);
                checksumPk2Go += (byte)((configWord >> 8) & 0xFF);
----------------------------------------------------------------------------------------------------------
//$$$Bequest333
        private static uint reverse16Bits(uint v)
        {
            v = ((v & 0x0000ff00) >> 8) | ((v & 0x000000ff) << 8);
            v = ((v & 0x0000f0f0) >> 4) | ((v & 0x00000f0f) << 4);
            v = ((v & 0x0000cccc) >> 2) | ((v & 0x00003333) << 2);
            v = ((v & 0x0000aaaa) >> 1) | ((v & 0x00005555) << 1);
            return v;
        }
//$$$


長くなりましたのでその2に続きます