PIC32&XC32のplib.hを自作する

2016年9月23日

ここにありました。ですが少しだけ無いマクロなどがあるようです。OSCREFconfigとか。

使うには以下の宣言が必要です。

#define _SUPPRESS_PLIB_WARNING
#define _DISABLE_OPENADC10_CONFIGPORT_WARNING

Harmonyがまともなら使うこともないのですが、以前バグだらけと書きましたが、いまはどうなんでしょうか。


C32コンパイラで有ったplib.hですがXC32にはありません。

一番困るのがキャッシュの設定やら、レジスタに直接書いても何故か反映しない物です。

それを出来るようにした関数群です。あとは使っていた数個の関数だけ作りました。

なので、C32?過去のXC32? Harmony?忘れました。ソースコードを参考に自作しました。アセンブラを使っています。これじゃあ私には無理です。

/* 
 * File:   plib.c
 * Author: SABA
 * 
 * for PIC32MX
 * 
 * Created on 2016/03/05, 23:31
 */

#include <p32xxxx.h>
#include <sys/attribs.h>
#include "plib.h"

// ----------------------------------------------------------------------------
//
//
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;   // 3 待機ステート
    
    // キャッシュ アクセス レジスタ
    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;    // キャッシュライン ロックビット 
}

// ----------------------------------------------------------------------------
//
//
unsigned int __attribute__((nomips16))  INTEnableInterrupts(void)
{
    unsigned int status = 0;

    asm volatile("ei    %0" : "=r"(status));

    return status;
}

// ----------------------------------------------------------------------------
//
//
void __attribute__ ((nomips16)) INTEnableSystemMultiVector(void)
{
    unsigned int val;

    // set the CP0 cause IV bit high
    asm volatile("mfc0   %0,$13" : "=r"(val));
    val |= 0x00800000;
    asm volatile("mtc0   %0,$13" : "+r"(val));

    INTCONSET = _INTCON_MVEC_MASK;

    // set the CP0 status IE bit high to turn on interrupts
    // INTEnableInterrupts();
}

// ----------------------------------------------------------------------------
//
//
void __attribute__ ((nomips16)) INTConfigureSystem(INT_SYSTEM_CONFIG config)
{
    unsigned int val;

    // set the CP0 cause IV bit high
    asm volatile("mfc0   %0,$13" : "=r"(val));
    val |= 0x00800000;
    asm volatile("mtc0   %0,$13" : "+r"(val));

    if(config == INT_SYSTEM_CONFIG_MULT_VECTOR)
        INTCONSET = _INTCON_MVEC_MASK;
    else
        INTCONCLR = _INTCON_MVEC_MASK;
}

// ----------------------------------------------------------------------------
//
//
unsigned int __attribute__((nomips16)) INTDisableInterrupts(void)
{
    unsigned int status = 0;

    asm volatile("di    %0" : "=r"(status));

    return status;
}

// ----------------------------------------------------------------------------
//
//
void __attribute__((nomips16))  INTRestoreInterrupts(unsigned int status)
{
    if(status & 0x00000001) {
        asm volatile("ei");
    }
    else {
        asm volatile("di");
    }
}

// ----------------------------------------------------------------------------
//
//
void __attribute__((nomips16)) OpenCoreTimer(unsigned int period)
{
	// clear the count reg
    asm volatile("mtc0   $0,$9");
    // set up the period in the compare reg
    asm volatile("mtc0   %0,$11" : "+r"(period));
}

PIC32

Posted by saba