PIC32キャッシュ設定が全く分からない件について

2017年2月6日

PIC32MX470F512L-I/PFを買いました。(USBをサポートしていますが、120MHzで動作させるとUSBのクロックがおかしくなるので、USB無し版を買えばよかったです)

今までは秋月で買ったPIC32MX2xxxシリーズを使っていました。

過去のXC32では一応plib.hがあったのですがコンパイルすると「そのうち無くなるよ」というエラーが出てコンパイルできません。色々#defineしてやっと使えますが、あやしいのでC32を未だに使っていました。最新のXC32にはもうありません。

そしてこれのプロジェクトを作るときXC32しか選択できません。

全てのレジスタを直接書けばいいのですが、一番困ったのが「SYSTEMConfigPerformance(GetSystemClock())」です。(Harmonyのソースコードで気が付いたのですが、PIC32MX1xx・PIC32MX2xxシリーズでは無意味だと。)

これはPIC32のクロック分周をリセットする機能とプログラムキャッシュを設定をするものです。ハードウェアマニュアルや個別マニュアルにはまともな説明がなく、Flashの読み込みwaitを設定するレジスタの説明もないので、クロック周波数によってどんな数字を入れるのかわかりません。

そしてこのキャッシュレジスタの設定、レジスタに書き込んでも反映されません。なぜなのかマニュアルにも書いていません。そして何をどう設定すれば一番いいのかも分からないので仕方がなく、過去のXC32?C32(どっちだったか忘れました)コンパイラの関数を参照して作りました。なんだかよくわかりませんが、アセンブラコードが入っています。全然わかりませんがここはあきらめて、「動いたオッケー」で放置することにしました。英語でちょっとだけ説明が書いてありますね。

void INTPrefetchEnableSet(uint32_t clk)
{
    register unsigned long tmp;
    uint8_t ws;
    
    // 30MHz 毎に1つ増やすらしいがどこにも資料に記述がなく、そう書いてあったHPの通りにしてみる。
    if(clk <= 30000000) {
        ws = 0;
    } else if(clk <= 60000000) {
        ws = 1;
    } else if(clk <= 90000000) {
        ws = 2;
    } else if(clk <= 120000000) {
        ws = 3;
    } else {
        ws = 4;
    }
    
    // プリフェッチ キャッシュ --------------------------------------------------
    //
    /* Set kseg0 coherency algorithm to "cacheable, non-coherent, write-back, 
     * write-allocate. This is needed for the prefetch buffer */
    asm("mfc0 %0,$16,0" :  "=r"(tmp));
    tmp = (tmp & ~7) | 3;
    asm("mtc0 %0,$16,0" :: "r" (tmp));
    
    // キャッシュ制御レジスタ
    CHETAGbits.LLOCK    = 0;    // キャッシュライン ロックビット
 
    CHECONbits.CHECOH   = 0;    // ロックされていないデータおよび命令キャッシュラインを無効にする
    CHECONbits.DCSZ     = 0;    // 1 ラインをデータキャッシュ用に使う
    CHECONbits.PREFEN   = 3;    // 予測プリフェッチ イネーブルビット
    CHECONbits.PFMWS    = ws;   // 待機ステート
    
    // キャッシュ アクセス レジスタ
    CHEACCbits.CHEWEN   = 0;    // CHEIDX<3:0> で選択したキャッシュラインに対する書き込みを許可する
    CHEACCbits.CHEIDX   = 0;    // キャッシュライン ID ビット
    
    // キャッシュ タグレジスタ
    CHETAGbits.LTAGBOOT = 1;    // キャッシュライン タグアドレス ブートビット
    CHETAGbits.LTAG     = 0;    // キャッシュライン タグアドレスビット
    CHETAGbits.LVALID   = 1;    // キャッシュライン 有効ビット
    CHETAGbits.LTYPE    = 1;    // キャッシュライン タイプビット
    CHETAGbits.LLOCK    = 0;    // キャッシュライン ロックビット 
}

と、言うような感じです。

PIC32

Posted by saba