* Raspberry Pi Pico 用の LCD 1.3 Waveshare のためのページ
-(by [[K]], 2024.08.20)

** (0)
-2024年7月下旬に https://www.amazon.co.jp/dp/B0982BMST9/ を買いました(1700円でした)。これで遊んでみます。
-https://www.waveshare.com/wiki/Pico-LCD-1.3 に情報があるようです。

** (1)
-https://www.waveshare.com/wiki/Pico-LCD-1.3 の Resource の Examples の Example demo をダウンロードして、アーカイブを解凍すると、 c / uf2 / LCD_1in3.uf2 があるので、これをpicoに入れてやると、デモが動く。動作テストができる。
- c / examples にコードはあるけど、setup()やloop()は見当たらない。

-なるほどー。Arduino IDEのC言語では static void func(int a) { ... } みたいに、関数にstatic属性を付けるとうまくコンパイルできないことがあるんだなー。
--これがわからなくて30分くらい悩んでしまった(笑)。

-書き方変更。
--[1]コンパイル済みのサンプルコードは動いた。
--[2]サンプルをソースからビルドする環境が用意できなかったので、初期化ルーチンを見よう見まねで作ってみた。
--[3]苦労したら、とりあえずコンパイルエラーが出ない程度にはなった。
--[4]さあ実行だ!・・・まあ当然だけど、見事にぶっ壊れて、picoに書き込むたびにArduino-IDEの再起動と、picoのBOTSEL押しながら再接続が必要になった。つらい。
--[5]なるほど、スタックを食いつぶしたせいでpicoがおかしくなっていたようだ。そのほか、picoをおかしくする重度のバグを直したら、IDEの再起動をしなくても平気になった。これではかどる!
--[6]しかしそれにしても画面には何も出ない。なんか出ないと前進しているのかどうかよくわからない。
--[7]お!ついになんか出たぞ!これはありがたい。・・・でも期待しているのとは違う・・・。
--[8]もしかしてエンディアンか?picoはビッグエンディアンじゃないのか??
--[9]エンディアンに依存しないように書き直したら・・・おお変わった!・・・うーん、まだおかしい。なんでそんな色になるんだよう。
--[10]な、なるほど・・・RGBではなく、BGRになっているっぽいな・・・。設定を直せば直るのだろうか。
--[11]適当にいじったら、RGBになった・・・かも?(オリジナルのソースコードのコメントの逆にしたらうまくいった!)
--[12]色については不満なし!しかし今度は座標系がおかしい。そういえばさっき、座標系のことが書いてあったな・・・。
--[13]座標系も直ったー。よっしゃー。

 #define LCD_RST_PIN  12
 #define LCD_DC_PIN   8
 #define LCD_BL_PIN   13
 #define LCD_CS_PIN   9
 #define LCD_CLK_PIN  10
 #define LCD_MOSI_PIN 11
 #define LCD_SCL_PIN  7
 #define LCD_SDA_PIN  6
 
 void GPIO_Init()
 {
   pinMode(LCD_RST_PIN, OUTPUT);
   pinMode(LCD_DC_PIN, OUTPUT);
   pinMode(LCD_CS_PIN, OUTPUT);
   pinMode(LCD_BL_PIN, OUTPUT);
   digitalWrite(LCD_CS_PIN, 1);
   digitalWrite(LCD_DC_PIN, 0);
   digitalWrite(LCD_BL_PIN, 1);
 }
 
 int slice_num;
 
 void Module_Init()
 {
   _spi_init(spi1, 10000 * 1000);
   gpio_set_function(LCD_CLK_PIN, GPIO_FUNC_SPI);
   gpio_set_function(LCD_MOSI_PIN, GPIO_FUNC_SPI);
  
   // GPIO Config
   GPIO_Init();
 
   // PWM Config
   gpio_set_function(LCD_BL_PIN, GPIO_FUNC_PWM);
   slice_num = pwm_gpio_to_slice_num(LCD_BL_PIN);
   pwm_set_wrap(slice_num, 100);
   pwm_set_chan_level(slice_num, PWM_CHAN_B, 1);  // setPwm(1);
   pwm_set_clkdiv(slice_num,50);
   pwm_set_enabled(slice_num, true);
   
   //I2C Config
   _i2c_init(i2c1,300*1000);
   gpio_set_function(LCD_SDA_PIN,GPIO_FUNC_I2C);
   gpio_set_function(LCD_SCL_PIN,GPIO_FUNC_I2C);
   gpio_pull_up(LCD_SDA_PIN);
   gpio_pull_up(LCD_SCL_PIN);
 }
 
 void LCD_1IN3_Reset()
 {
   digitalWrite(LCD_RST_PIN, 1);
   delay(100);
   digitalWrite(LCD_RST_PIN, 0);
   delay(100);
   digitalWrite(LCD_RST_PIN, 1);
   delay(100);
 }
 
 void LCD_1IN3_SendCommand(uint8_t dat)
 {
   digitalWrite(LCD_DC_PIN, 0);
   digitalWrite(LCD_CS_PIN, 0);
   spi_write_blocking(spi1, &dat, 1);
   digitalWrite(LCD_CS_PIN, 1);
 }
 
 void LCD_1IN3_SendData_8Bit(int dat)
 {
   uint8_t a[1];
   a[0] = dat & 0xff;
   digitalWrite(LCD_DC_PIN, 1);
   digitalWrite(LCD_CS_PIN, 0);
   spi_write_blocking(spi1, a, 1);
   digitalWrite(LCD_CS_PIN, 1);
 }
 
 void LCD_1IN3_SentData_16Bit(int dat)
 {
   digitalWrite(LCD_DC_PIN, 1);
   digitalWrite(LCD_CS_PIN, 0);
   uint8_t a[2];
   a[0] = (dat >> 8) & 0xff;
   a[1] = dat & 0xff;
   spi_write_blocking(spi1, a, 2);
   digitalWrite(LCD_CS_PIN, 1);
 }
 
 void LCD_1IN3_InitReg()
 {
   LCD_1IN3_SendCommand(0x3A);
   LCD_1IN3_SendData_8Bit(0x05);
 
   LCD_1IN3_SendCommand(0xB2);
   LCD_1IN3_SendData_8Bit(0x0C);
   LCD_1IN3_SendData_8Bit(0x0C);
   LCD_1IN3_SendData_8Bit(0x00);
   LCD_1IN3_SendData_8Bit(0x33);
   LCD_1IN3_SendData_8Bit(0x33);
 
   LCD_1IN3_SendCommand(0xB7);  //Gate Control
   LCD_1IN3_SendData_8Bit(0x35);
 
   LCD_1IN3_SendCommand(0xBB);  //VCOM Setting
   LCD_1IN3_SendData_8Bit(0x19);
 
   LCD_1IN3_SendCommand(0xC0); //LCM Control     
   LCD_1IN3_SendData_8Bit(0x2C);
 
   LCD_1IN3_SendCommand(0xC2);  //VDV and VRH Command Enable
   LCD_1IN3_SendData_8Bit(0x01);
   LCD_1IN3_SendCommand(0xC3);  //VRH Set
   LCD_1IN3_SendData_8Bit(0x12);
   LCD_1IN3_SendCommand(0xC4);  //VDV Set
   LCD_1IN3_SendData_8Bit(0x20);
 
   LCD_1IN3_SendCommand(0xC6);  //Frame Rate Control in Normal Mode
   LCD_1IN3_SendData_8Bit(0x0F);
  
   LCD_1IN3_SendCommand(0xD0);  // Power Control 1
   LCD_1IN3_SendData_8Bit(0xA4);
   LCD_1IN3_SendData_8Bit(0xA1);
 
   LCD_1IN3_SendCommand(0xE0);  //Positive Voltage Gamma Control
   LCD_1IN3_SendData_8Bit(0xD0);
   LCD_1IN3_SendData_8Bit(0x04);
   LCD_1IN3_SendData_8Bit(0x0D);
   LCD_1IN3_SendData_8Bit(0x11);
   LCD_1IN3_SendData_8Bit(0x13);
   LCD_1IN3_SendData_8Bit(0x2B);
   LCD_1IN3_SendData_8Bit(0x3F);
   LCD_1IN3_SendData_8Bit(0x54);
   LCD_1IN3_SendData_8Bit(0x4C);
   LCD_1IN3_SendData_8Bit(0x18);
   LCD_1IN3_SendData_8Bit(0x0D);
   LCD_1IN3_SendData_8Bit(0x0B);
   LCD_1IN3_SendData_8Bit(0x1F);
   LCD_1IN3_SendData_8Bit(0x23);
 
   LCD_1IN3_SendCommand(0xE1);  //Negative Voltage Gamma Control
   LCD_1IN3_SendData_8Bit(0xD0);
   LCD_1IN3_SendData_8Bit(0x04);
   LCD_1IN3_SendData_8Bit(0x0C);
   LCD_1IN3_SendData_8Bit(0x11);
   LCD_1IN3_SendData_8Bit(0x13);
   LCD_1IN3_SendData_8Bit(0x2C);
   LCD_1IN3_SendData_8Bit(0x3F);
   LCD_1IN3_SendData_8Bit(0x44);
   LCD_1IN3_SendData_8Bit(0x51);
   LCD_1IN3_SendData_8Bit(0x2F);
   LCD_1IN3_SendData_8Bit(0x1F);
   LCD_1IN3_SendData_8Bit(0x1F);
   LCD_1IN3_SendData_8Bit(0x20);
   LCD_1IN3_SendData_8Bit(0x23);
 
   LCD_1IN3_SendCommand(0x21);  //Display Inversion On
   LCD_1IN3_SendCommand(0x11);  //Sleep Out
   LCD_1IN3_SendCommand(0x29);  //Display On
 }
 
 void LCD_1IN3_Init()
 {
   pwm_set_chan_level(slice_num, PWM_CHAN_B, 90); // setPwm(90);
   //Hardware reset
   LCD_1IN3_Reset();
 
   //Set the resolution and scanning method of the screen
   LCD_1IN3_SendCommand(0x36); //MX, MY, RGB mode
   LCD_1IN3_SendData_8Bit(0x70);	//0x08 set RGB
  
   //Set the initialization register
   LCD_1IN3_InitReg();
 }
 
 uint16_t col(int r, int g, int b)
 // r5:g6:b5 形式を計算してエンディアンをひっくり返す.
 {
   return (b << 8 | g << 13 | g >> 3 | r << 3) & 0xffff;
 }
 
 void bitblt(int sx, int sy, int x0, int y0, uint16_t *buf, int xBufSiz)
 {
   LCD_1IN3_SendCommand(0x2A);
   LCD_1IN3_SendData_8Bit(0x00);
   LCD_1IN3_SendData_8Bit(x0);
   LCD_1IN3_SendData_8Bit(0x00);
   LCD_1IN3_SendData_8Bit(x0 + sx - 1);
 
   //set the Y coordinates
   LCD_1IN3_SendCommand(0x2B);
   LCD_1IN3_SendData_8Bit(0x00);
   LCD_1IN3_SendData_8Bit(y0);
   LCD_1IN3_SendData_8Bit(0x00);
   LCD_1IN3_SendData_8Bit(y0 + sy - 1);
 
   LCD_1IN3_SendCommand(0X2C);
   digitalWrite(LCD_DC_PIN, 1);
   digitalWrite(LCD_CS_PIN, 0);
   int i, j;
   for (i = 0; i < sy; i++) {
     spi_write_blocking(spi1, (uint8_t *) buf, sx * 2);
     buf += xBufSiz;
   }
   digitalWrite(LCD_CS_PIN, 1);
   LCD_1IN3_SendCommand(0X29);
 }
 
 // グラデーション表示.
 
 void setup()
 {
   delay(100);
   Module_Init();
   pwm_set_chan_level(slice_num, PWM_CHAN_B, 50);  // setPwm(50);
   LCD_1IN3_Init();
   uint16_t *buf = (uint16_t *) malloc(240 * 240 * 2);
   int x, y, i = 0;
   for (y = 0; y < 240; y++) {
     for (x = 0; x < 240; x++) {
       buf[i++] = buf[i++] = col((y + 144) / 12, (x + 144) / 6, 0); 
     }
   }
   bitblt(240, 240, 0, 0, buf, 240);
 }
 
 void loop() {
   // put your main code here, to run repeatedly:
   delay(1000);
 }

** (2)
-回転キューブとボタン入力のテスト。ソースは上記のbitblt()までは共通。

 // 回転キューブとボタン入力のテスト.
 
 #define KeyA_Pin  15
 
 uint16_t *gbuf;
 int sqr[24] = { 7,6,2,3, 6,4,0,2, 1,0,4,5, 7,3,1,5, 3,2,0,1, 7,5,4,6 };
 int vertx[8] = { -50, -50, -50, -50, +50, +50, +50, +50 };
 int verty[8] = { -50, -50, +50, +50, -50, -50, +50, +50 };
 int vertz[8] = { -50, +50, -50, +50, -50, +50, -50, +50 };
 int thx = 0, thy = 0, thz = 0;
 uint16_t colTbl[6];
 int *buf0, *buf1;
 
 void setup()
 {
   delay(100);
   Module_Init();
   pwm_set_chan_level(slice_num, PWM_CHAN_B, 50);  // setPwm(50);
   LCD_1IN3_Init();
   pinMode(KeyA_Pin, INPUT_PULLUP);
   gbuf = (uint16_t *) malloc(240 * 240 * 2);
   int i;
   for (i = 0; i < 240 * 240; i++) {
     gbuf[i] = 0x0000;
   }
   bitblt(240, 240, 0, 0, gbuf, 240);
   colTbl[0] = col(0x00 >> 3, 0x00 >> 2, 0xff >> 3);
   colTbl[1] = col(0x00 >> 3, 0xff >> 2, 0x00 >> 3);
   colTbl[2] = col(0x00 >> 3, 0xff >> 2, 0xff >> 3);
   colTbl[3] = col(0xff >> 3, 0x00 >> 2, 0x00 >> 3);
   colTbl[4] = col(0xff >> 3, 0x00 >> 2, 0xff >> 3);
   colTbl[5] = col(0xff >> 3, 0xff >> 2, 0x00 >> 3);
   buf0 = (int *) malloc(160 * 4);
   buf1 = (int *) malloc(160 * 4);
 }
 
 int32_t aFf16Sin(int x) {	return (int32_t) (sin(x * (2 * 3.14159265358979323 / 65536)) * 65536); }
 int32_t aFf16Cos(int x) { return (int32_t) (cos(x * (2 * 3.14159265358979323 / 65536)) * 65536); }
 int32_t aFf16Sqrt(int x) { return (int32_t) (sqrt(x * (1.0 / 65536)) * 65536); }
 int32_t aMul64Shr(int i, int j, int k) { return ((int64_t) i) * ((int64_t) j) >> k; }
 
 void aFillRect(int sx, int sy, int x0, int y0, uint16_t c)
 {
   uint16_t *p = gbuf + y0 * 240 + x0;
   int i, j;
   for (j = 0; j < sy; j++) {
     for (i = 0; i < sx; i++) {
       p[i] = c;
     }
     p += 240;
   }
 }
 
 void loop()
 {
   if (digitalRead(KeyA_Pin) == 0) { thx = thy = thz = 0; } // Aボタンを押すと初期状態に戻る.
   thx = (thx + 182) & 0xffff;
   thy = (thy + 273) & 0xffff;
   thz = (thz + 364) & 0xffff;
   int xp = aFf16Cos(thx), xa = aFf16Sin(thx);
   int yp = aFf16Cos(thy), ya = aFf16Sin(thy);
   int zp = aFf16Cos(thz), za = aFf16Sin(thz);
   int i, t, l, vx[8], vy[8], vz[8], scx[8], scy[8], centerz[7];
   for (i = 0; i < 240 * 240; i++) {
     gbuf[i] = 0x0000;
   }
   for (i = 0; i < 8; i++) {
     int zt = vertz[i] * xp + verty[i] * xa;
     int yt = verty[i] * xp - vertz[i] * xa;
     int xt = vertx[i] * yp + aMul64Shr(zt, ya, 16);
     vz[i] = aMul64Shr(zt, yp, 16) - vertx[i] * ya;
     vx[i] = aMul64Shr(xt, zp, 16) - aMul64Shr(yt, za, 16); // z軸の周りに回す.
     vy[i] = aMul64Shr(yt, zp, 16) + aMul64Shr(xt, za, 16);
     t = 4915200 / ((vz[i] + 13107200) >> 16);
     scx[i] = aMul64Shr(vx[i], t, 31) + 80;
     scy[i] = aMul64Shr(vy[i], t, 31) + 80;
   }
   for (l = 0; l < 6 * 4; l = l + 4) {
     centerz[l / 4] = vz[sqr[l]] + vz[sqr[l+1]] + vz[sqr[l+2]] + vz[sqr[l+3]] + 0x70000000;
   }
   centerz[6] = 0;
   for (;; centerz[i] = 0) {
     t = centerz[0]; i = 0;
     for (l = 1; l < 7; l++) {
       if (t <= centerz[l]) { t = centerz[l]; i = l; }
     }
     if (i >= 6) break;
     l = i * 4; int l1 = l + 4, j = sqr[l + 3], p0x = scx[j], p0y = scy[j];
     int ymin = 99999, ymax = 0, c = colTbl[i];
     int *buf, dx, x, y, y0, y1, p1x, p1y;
     for (; l < l1; l++) {
       j = sqr[l]; int p1x = scx[j], p1y = scy[j];
       if (ymin > p1y) { ymin = p1y; }
       if (ymax < p1y) { ymax = p1y; }
       if (p0y != p1y) {
         if (p0y < p1y) {
           buf = buf0; y0 = p0y; y1 = p1y; dx = p1x - p0x; x = p0x;
         } else {
           buf = buf1; y0 = p1y; y1 = p0y; dx = p0x - p1x; x = p1x;
         }
         dx = dx * 65536 / (y1 - y0);
         x = x * 65536 + 0x8000;
         if (dx < 0) { x = x - 0x10000; }
         for (y = y0; y <= y1; y++) {
           buf[y] = x >> 16;
           x = x + dx;
         }
       }
       p0x = p1x; p0y = p1y;
     }
     for (y = ymin; y <= ymax; y++) {
       p0x = buf0[y];
       p1x = buf1[y];
       if (p0x <= p1x) {
         aFillRect(p1x - p0x + 1, 1, p0x, y, c);
       } else {
         aFillRect(p0x - p1x + 1, 1, p1x, y, c);
       }
     }
   }
   bitblt(160, 160, 40, 40, gbuf, 240);
 }

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS