覚え書きTOP

2018/08/16
RL78関係の記事はこちらに移動しました。
下記ページは今後更新しません。


2016/10/24
 CC-RLでの開発開始時の設定 無償評価版はここからDL
 CS+のパラメータなどの設定情報。
 なおCC-RLではポートのBITの触り方が変わった。またiodefine.hがソースとして出てくるようになった。
  P7_bit.no6 = 1; // P76 Out

既に設定変更済みのPRJを持っている場合はインポートすればOK。
真っさらから始める場合は下の方の設定を変更する。
CREFを使用するに変更、これをしないとソースモードでのstataic関数への関数ジャンプ(F12)が出来ない。
最適化はデバッグ優先に変更、これでデバッグ時の変数や動作を追いやすくなる。
 
 
コメントのネストは自分には必須。 
 
 
WDTはコード生成では「使用する」に設定しておき、オプションバイトで停止してる(先にコード生成してから変更する)。理由
ROMとRAMの使用量を表示させてる(ビルド終了時にメッセージ欄に出てくる)。
 
デバッグを指定の関数から始めるためにはここを変更する(関数名の先頭には '_' アンダースコアが必要だ)。
宣言してあっても実際にコールしてない関数名を書いちゃうと、いきなりゼロ番地に飛んだりするので要注意。


2016/10/23
 PWMしてみた
 RL78ではPWMをするときにタイマを最低でも二つ使う。
 一つはマスターと呼び、こいつはPWM周波数を決める。
 もう一つはスレーブと呼び、こいつはPWMのデューティーを決める。
 スレーブは複数有っても構わなくて、複数有れば複数のデューティーのPWMを同時に出力可能だ(マスターは一個だけなので周波数は同じになる)。
 今回はマスター一個にスレーブ二個で試した。つまりタイマを3個使う。
  マスター:TAU1のチャンネル0
  スレーブ:TAU1のチャンネル1と2
 コード生成でこんな感じで設定した(スレーブのチャンネル2はデューティーを10%にしてる)。
 割込みは使わないけど、実験用に発生させることにした。


 んで端子配置表へ反映させると、TO11とTO12が端子配置される。
 更にコード生成させると”R_TAU1_Create()"にそれなりのコードが出力される。
 このコードの中で大事なのはデューティーを決めるレジスタとその値だ。
 なんとなくわざとらしい数値がある(0640と0140)んで、これをいじってデューティーが変わるか調べれば良い。


 今回はスレーブのチャンネル1だけを調べてるんで、オシロをTO11(P30)に接続しておく。
 コードはこんな感じで作ってみた。
 デューティーは50%で0x640だから100%なら二倍の0xC80だろうってことで(コード生成時に100%にすれば計算するまでもなかった)。
 ステップ実行するとオシロに表示される波形の幅が変化する。
 RL78のハードウエアマニュアルを読むのが面倒くさい自分には、コード生成は確かに便利だわ。

 
//================================================================================================
// TO11/12 16ビット・タイマ出力(モーターPWM)
//================================================================================================
void To11Main(void)
{
    To11Duty(80); // duty 80%
    R_TAU1_Channel0_Start();
    To11Duty(10); // duty 10%
    R_TAU1_Channel0_Stop();
}
// PWMのduty設定:duty比 0〜100(%)
void To11Duty(uint8_t d)
{
    if (d >= 100) TDR11 = 0x0C80U;  // 100%=0x0C80U, 50%=0x0640U  
    else TDR11 = (0x0C80U / 100U) * d;
}
void To10Intr(void){    NOP();  }   // PWMマスター10INTR
void To11Intr(void){    NOP();  }   // PWMスレーブ11INTR
// TO12 16ビット・タイマ12出力(予備PWM出力)
void To12Main(void)
{
    TDR12 = 0x0C80U;    // duty 100%
    R_TAU1_Channel0_Start();
    TDR12 = 0x0640U;    // duty 50%
    TDR12 = 0x0U;  // duty 0%
    R_TAU1_Channel0_Stop();
}
void To12Intr(void){    NOP();  }   // PWMスレーブ12INTR


2016/10/23
 SPIのスレーブ ルネサスサンプル
 SPIのマスターは簡単だけど、スレーブってどうやるんだろ?
 今のところ思いついてる方法をメモ。
 ※SPIのDMA転送は面倒くさいらしいからやめた方が良いようだ。

 SPIってのは要するにシフトレジスタでシリパラ変換してるんだよね?
 だとしたらシリパラ変換の完了割込み(シリパラINTRと略)で、シフトレジスタからデータをINしてバッファに蓄えれば良いんじゃない。
 ただしソフトで動かすからハンドシェークが必要だ。
<スレーブ受信の第一案>
 1:シリパラINTRが発生したらCSがenableであることを確認。
 2:buf[cnt++]にデータをセットする。
 ただこの方法だとCSがdisableの時にもシリパラINTRが発生するんで余りよろしくないかも。

<スレーブ受信の第二案>
 1:CSがenableになったら割込みを発生させ、その中でシリパラINTRの発生を許可する(マスター側は少し待つ必要有り)。
 2:シリパラINTRが発生したら無条件にbuf[cnt++]にデータをセットする。
 3:CSがdisableになったら割込みを発生させ、その中でシリパラINTRの発生を禁止する。
 これかな?
 CSの上下両エッヂでの割込みを使えば一番良い感じかも。
 この方法ならUART受信みたいに、勝手に裏で受信できるから良さそうだ。

 送信はどうやるか。
 マスターからのクロックはいつ来るか分からないのだから・・・
<スレーブ送信の第一案>
 1:パラシリレジスタに予めデータをセットしておく。
 2:マスターに送信準備完了の合図を適当なポートで示す。
 3:パラシリ変換完了INTRで次のデータをパラシリレジスタにセット。
 こうか?
 いずれ実験してみよう。



2016/10/29
 ILI9341+グラフィックLCD 
参考HP1 参考HP2 データシート
 グラフィックLCDを使うことになった。
 LCDを直接操作するわけじゃなくて、コントローラICのILI9341(ILI9340でも動くと思う)のいじり方。
 ・RL78と9341は16bitのパラレルで接続してる。
 ・リセットはハード的に発生してる。

 ってことで、あちこちググり回って見付けたのが上記の参考HP。
 とても分かりやすく、更にソースも載せてくれてるんでいたって簡単に完成した。有り難うございます。
 ところでどのHPもCPUと9341をSPIで接続してる。
 今回は16bitパラレル接続(P7/8)なんで、IO部分だけを修正すれば動くはずと目星を付けて作ったのがこれ。
 要するにSPIで出力してるのをポート出力に変更しただけ。

IM0〜3を0001にセットすることで16bitバスになる(9341マニュアルより抜粋)。
またレジスタへのアクセスは8bit幅だけど、GRAMは16bit幅でアクセスすることが読み取れる。




CMDを書くときはDCX=L、DATAを書くときはDCX=Hにしておいて、WRXで↑エッジを出してやる。



GRAMに上位8bitゼロで書き込むと赤だけ表示されなかった(CPUボードは北斗電子製)。
この後で16bitで書き込んだら赤も表示されたから、上位側が赤なんだろな。


 
//
// lcd.c ILI9341+4DLCD-28QA 2016/10/15
//   http://imagewriteriij.blogspot.jp/2014/01/raspberry-pi-9-lcd-1.html
//   http://nopnop2002.webcrow.jp/TFT/ILI9340-1.html
//
#include "r_cg_macrodriver.h"
#include "iodefine.h"
#include "r_cg_userdefine.h"
// LCD Ports define
#define LCD_BKL     P3_bit.no1  // BackLight
#define LCD_CSX     P6_bit.no5  // CSX
#define LCD_DCX     P6_bit.no4  // DCX
#define LCD_WRX     P6_bit.no7  // WRX
#define LCD_RDX     P6_bit.no6  // RDX
// Prototype
static void lcd_test(uint16_t r, uint16_t g, uint16_t b);
static void clear(uint16_t r, uint16_t g, uint16_t b);
static void colorbar(void);
static void write_dc(uint8_t dc, uint8_t c);
static void write_dc_w(uint16_t w);
static void write_dc_w16(uint16_t w);
static void lcd_init(void);
static void addset(uint16_t x, uint16_t y);
static uint16_t rgb565_conv(uint16_t r, uint16_t g, uint16_t b);
//================================================================================================
// LCD main
//================================================================================================
void LcdMain(void)
{
/* 手動でリセットするなら・・・
 LCD_CSX = 0;   // CS=L(これは要らないかも)
 LCD_DCX = 1;   // D/C = H
 RESET = 0;     // Reset = L
 delay1ms(100); // delay 100ms
 RESET = 1;     // Reset = 1
 delay1ms(100); // delay 100ms
*/
    LCD_BKL = 1;    // バックライトON
    LCD_CSX = 0;    // CS=L
    lcd_init();

    lcd_test(0, 255, 255);
    lcd_test(255, 255, 0);
    lcd_test(255, 0, 255);

    LCD_CSX = 1;    // CS=H
    LCD_BKL = 0;    // バックライトOFF
}
// デバッグ用のLCD表示
void lcd_test(uint16_t r, uint16_t g, uint16_t b)
{
    clear(r, g, b);
    colorbar();
}
// lcd initial
static void lcd_init(void)
{
    LCD_WRX = 1;
    LCD_RDX = 1;
    delay1ms(25);
    write_dc(0,0xC0);       //Power control 
    write_dc(1,0x23);
    write_dc(0,0xC1);       //Power control 
    write_dc(1,0x10);
    write_dc(0,0xC5);       //VCM control 
    write_dc(1,0x3e);
    write_dc(1,0x28); 
    write_dc(0,0xC7);       //VCM control2 
    write_dc(1,0x86);
    write_dc(0,0x36);       // Memory Access Control 
    write_dc(1,0x48);
    write_dc(0,0x3A);       
    write_dc(1,0x55); 
    write_dc(0,0xB1);       
    write_dc(1,0x00);    
    write_dc(1,0x18); 
    write_dc(0,0xB6);       // Display Function Control 
    write_dc(1,0x08); 
    write_dc(1,0x82);
    write_dc(1,0x27);    
    write_dc(0,0xF2);       // 3Gamma Function Disable 
    write_dc(1,0x00); 
    write_dc(0,0x26);       //Gamma curve selected 
    write_dc(1,0x01); 
    write_dc(0,0xE0);       //Set Gamma 
    write_dc(1,0x0F); 
    write_dc(1,0x31); 
    write_dc(1,0x2B); 
    write_dc(1,0x0C); 
    write_dc(1,0x0E); 
    write_dc(1,0x08); 
    write_dc(1,0x4E); 
    write_dc(1,0xF1); 
    write_dc(1,0x37); 
    write_dc(1,0x07); 
    write_dc(1,0x10); 
    write_dc(1,0x03); 
    write_dc(1,0x0E); 
    write_dc(1,0x09); 
    write_dc(1,0x00); 
    write_dc(0,0XE1);       //Set Gamma 
    write_dc(1,0x00); 
    write_dc(1,0x0E); 
    write_dc(1,0x14); 
    write_dc(1,0x03); 
    write_dc(1,0x11); 
    write_dc(1,0x07); 
    write_dc(1,0x31); 
    write_dc(1,0xC1); 
    write_dc(1,0x48); 
    write_dc(1,0x08); 
    write_dc(1,0x0F); 
    write_dc(1,0x0C); 
    write_dc(1,0x31); 
    write_dc(1,0x36); 
    write_dc(1,0x0F); 
    write_dc(0,0x11);       //Exit Sleep 
    delay1ms(120); 
    write_dc(0,0x29);       //Display on 
    write_dc(0,0x2c);       //Memory Write
}
// clear
static void clear(uint16_t r, uint16_t g, uint16_t b)
{
    int i,j; 
    for (i=0;i<240;i++) {       // x = 0 to 239
        for(j=0;j<320;j++) {    // y = 0 to 319 
            addset(i,j);
            write_dc_w16(rgb565_conv(r, g, b));
        }
    }
}
// write color bar
static void colorbar(void)
{
    int i,j; 
    for(i=0;i<240;i++){         // x = 0 to 239
        for(j=0;j<320;j++){     // y = 0 to 319 
            if(j<106) {
                addset(i,j);
                write_dc_w16(rgb565_conv(255,0,0)); //red
            } else if(j<212) {
                addset(i,j);
                write_dc_w16(rgb565_conv(0,255,0)); //green
            } else { 
                addset(i,j);
                write_dc_w16(rgb565_conv(0,0,255)); //blue
            }
        }
    }
}
// set address
static void addset(uint16_t x, uint16_t y)
{
    write_dc(0,0x2A); // set column(x) address
    write_dc_w(x);
    write_dc_w(x);
    write_dc(0,0x2B); // set Page(y) address
    write_dc_w(y);
    write_dc_w(y);
    write_dc(0,0x2C); // Memory Write
}
// RGB565 conversion
// RGB565 is R(5)+G(6)+B(5)=16bit color format.
// Bit image "RRRRRGGGGGGBBBBB"
static uint16_t rgb565_conv(uint16_t r,uint16_t g,uint16_t b)
{
    uint16_t RR,GG,BB;
    RR = (r * 31 / 255) << 11;
    GG = (g * 63 / 255) << 5;
    BB = (b * 31 / 255);
    return(RR | GG | BB);
}
// Write data/command
static void write_dc(uint8_t dc, uint8_t c) 
{
    LCD_DCX = dc;   // 0=command, 1=data
    P7 = c;         // 下位8bitのみ(上位8bitはdont care)
    LCD_WRX = 0;    // WR out
    NOP();
    LCD_WRX = 1;    
}
// Write data word
static void write_dc_w(uint16_t w)
{
    uint8_t hi,lo;
    hi = (uint8_t)(w >> 8);
    lo = (uint8_t)(w & 0x00FF);
    write_dc(1,hi);
    write_dc(1,lo);
}
// Write data word by 16bit
static void write_dc_w16(uint16_t w)
{
    uint8_t hi,lo;
    hi = (uint8_t)(w >> 8);
    lo = (uint8_t)(w & 0x00FF);
    LCD_DCX = 1;    // 1=data
    P8 = hi;        // 上位8bit
    P7 = lo;        // 下位8bit
    LCD_WRX = 0;    // WR out
    NOP();
    LCD_WRX = 1;    
}


2016/11/09
 この関数のコール元はどこ?
 コールスタックの表示方法を見付けた。
デバッガマニュアルP98



”E1202855 起動時にフラッシュROMを消去しろ”が出た
 デバッグしようとすると「E1202855の”起動時にフラッシュROMを消去しろ”」が出る。
 いくら消去しても何度も出る。
 原因はプロジェクトを取り違えてデバッグしてた(CPUを間違えてた)。
 「CPUの選択を間違えてるよ」とは出てくれないんだなこれが。
 RFPだとシグネチャーエラーとか出るけど、CS+では出ない・・・CPUの型番チェックをしてない?
 この手の統一性の無さはユーザーに不親切じゃん ←
なんだかんだ文句をたれながらCS+を有り難く使ってるやつ(^^;
 ちなみに本当にフラッシュを消去してからデバッグするなら、”起動時にフラッシュROMを消去する”を”はい”にするんだそうだ。



かなり便利なスマート・マニュアル
 CS+V6で追加された機能。
 コード生成で自動生成されたコードを確認・改造する時にチョー便利。
 マウスをレジスタ名に持って行くとマニュアルの該当ページが表示される(自分の場合はフローティングにしてサブディスプレイに表示してる)。
 いちいちPDFのマニュアルを検索して開く必要が無い。
 おお〜これは便利。日本語マニュアルだし、ルネサスも最近は大分良いな〜











覚え書きTOP