前回作ったものが表示が遅い+メモリリークで落ちるため、いくつか見直しを行った
実際の表示はわからないけど、LCDへの書き出し処理は大体16fpsくらい できているみたい
フリー素材のGIF動画を使わせてもらった「いいね!」
https://www.pakutaso.com/gif/gifpost-135.html
やったことは
・vecterの開放(vector<uint8_t>().swap(tbx);)
・SPIの開放忘れ(free(&spi);)
やってもあまり効果なかったこと
・SPI_IOC_MESSAGEのサイズ 結局1度に送れるのは4096Byte?
差分はここんな感じ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* LibST7735S.cpp | |
* | |
* Created on: 2018/02/05 | |
* Author: adeno | |
*/ | |
#include "LibST7735S.h" | |
#define LCD_X_OFFSET 2 | |
#define LCD_Y_OFFSET 1 | |
LibST7735S::LibST7735S(int SPI_Bus, int SPI_Ce, int SPI_Speed,uint8_t SPI_Mode,int a0, int rst, | |
uint8_t width,uint8_t height) { | |
this->SPI_Bus = SPI_Bus; | |
this->SPI_Ce = SPI_Ce; | |
this->SPI_Speed = SPI_Speed; | |
this->SPI_Mode = SPI_Mode; | |
this->a0 = a0; | |
this->rst = rst; | |
spi = new LibSpi(this->SPI_Bus,this->SPI_Ce,this->SPI_Speed,this->SPI_Mode); | |
this->createDisplay(width,height,COLOR_FORMAT_18BIT); | |
} | |
LibST7735S::~LibST7735S() { | |
dcpin->portClose(); | |
rstpin->portClose(); | |
delete(spi); | |
} | |
void LibST7735S::createDisplay(uint8_t width,uint8_t height,uint8_t color_format){ | |
this->width = width; | |
this->height = height; | |
/* Reset Pin */ | |
if(this->rst != -1) | |
{ | |
this->rstpin = new LibGpio(this->rst,this->OUTPUT); //RST 出力方向 | |
this->rstpin->setVal(this->HIGH); | |
this->HWReset(); | |
} | |
/* Data/Command pin */ | |
this->dcpin = new LibGpio(this->a0,this->OUTPUT); //RST 出力方向 | |
this->dcpin->setVal(this->HIGH); | |
/* Initialzie display */ | |
this->writeCommand(CMD_SW_RESET); usleep(150*1000); //150ms | |
this->writeCommand(CMD_SLEEP_OUT); usleep(150*1000); //150ms | |
this->setMADCTL(0,0,0,0,0,0); | |
// setWindow(1, 1, width, height); | |
this->setColorFormat(color_format); | |
// this->writeCommand(CMD_TEON); this->writeData(0x01); usleep(100*1000); //100ms | |
writeCommand(CMD_DISPLAY_ON); usleep(100*1000); //100ms | |
} | |
void LibST7735S::fillScreen(uint8_t red, uint8_t green, uint8_t blue){ | |
this->fillRect(0,0,this->width,this->height,red, green, blue); | |
} | |
void LibST7735S::fillRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, | |
uint8_t red, uint8_t green, uint8_t blue){ | |
vector<uint8_t> tbx(w*h*3); | |
this->setWindow(LCD_X_OFFSET+x, LCD_Y_OFFSET+y, | |
LCD_X_OFFSET+x+w-1, LCD_Y_OFFSET+y+h-1); | |
int i=0; | |
for(int wy=0; wy<h; wy++){ | |
for(int wx=0; wx<w; wx++){ | |
tbx[i] = blue; | |
tbx[i+1] = green; | |
tbx[i+2] = red; | |
// tbx.push_back(blue); tbx.push_back(green); tbx.push_back(red); | |
i+=3; | |
} | |
} | |
activeRAMWrite(); | |
this->writeData_vector2(&tbx); | |
vector<uint8_t>().swap(tbx); | |
} | |
void LibST7735S::drawPx(uint8_t x, uint8_t y,uint8_t red, uint8_t green, uint8_t blue){ | |
/* Check x and y */ | |
// if((x >= this->width) || (y >= this->height)) return; | |
uint8_t tbram[3] = {blue,green,red}; | |
this->setWindow(LCD_X_OFFSET+x, LCD_X_OFFSET+y, LCD_X_OFFSET+x, LCD_X_OFFSET+y); | |
activeRAMWrite(); | |
this->writeData(3,tbram); | |
} | |
void LibST7735S::drawImage(uint8_t x, uint8_t y, uint8_t w, uint8_t h,vector<char>* d){ | |
//d・・・BGR | |
vector<uint8_t> tbx(w*h*3);//,tbx2; | |
this->setWindow(LCD_X_OFFSET+x, LCD_Y_OFFSET+y, | |
LCD_X_OFFSET+x+w-1, LCD_Y_OFFSET+y+h-1); | |
activeRAMWrite(); | |
int i=0; | |
// for(int wy=0; wy<h; wy++){ | |
// for(int wx=0; wx<w; wx++){ | |
// tbx.push_back((uint8_t)d[d.size()-(i+1)]); //blue | |
// tbx.push_back((uint8_t)d[d.size()-(i+2)]); //green | |
// tbx.push_back((uint8_t)d[d.size()-(i)]); //red | |
// i=i+3; | |
// } | |
// reverse_copy(tbx.begin(),tbx.end(),back_inserter(tbx2)); | |
//// copy(tbx.begin(),tbx.end(),back_inserter(tbx2)); | |
// tbx.clear(); | |
// } | |
// if(tbx2.size() > 0){ | |
// this->writeData_vector2(tbx2); | |
// tbx2.clear(); | |
// } | |
vector<char> dp = *d; | |
int index,s=d->size(); | |
for(int dy=0; dy<h; dy++){ | |
for(int dx=0; dx<3*w; dx+=3){ | |
index = s -3*w*dy +dx -3*w; | |
tbx[i] = (uint8_t)dp[index]; | |
tbx[i+1] = (uint8_t)dp[index+1]; | |
tbx[i+2] = (uint8_t)dp[index+2]; | |
// tbx.push_back((uint8_t)d[index]); //blue | |
// tbx.push_back((uint8_t)d[index+1]); //green | |
// tbx.push_back((uint8_t)d[index+2]); //red | |
i+=3; | |
} | |
} | |
this->writeData_vector2(&tbx); | |
tbx.clear(); | |
} | |
void LibST7735S::drawImage2(uint8_t x, uint8_t y, uint8_t w, uint8_t h,vector<char>* d){ | |
//d・・・BGR | |
vector<uint8_t> tbx(w*h*3); | |
this->setWindow(LCD_X_OFFSET+x, LCD_Y_OFFSET+y, | |
LCD_X_OFFSET+x+w-1, LCD_Y_OFFSET+y+h-1); | |
activeRAMWrite(); | |
int i=0; | |
vector<char> dp = *d; | |
int index,s=d->size(); | |
for(int dy=0; dy<h; dy++){ | |
for(int dx=0; dx<3*w; dx+=3){ | |
index = s -3*w*dy +dx -3*w; | |
tbx[i] = (uint8_t)dp[index]; | |
tbx[i+1] = (uint8_t)dp[index+1]; | |
tbx[i+2] = (uint8_t)dp[index+2]; | |
i+=3; | |
} | |
} | |
this->writeData_vector3(&tbx); | |
tbx.clear(); | |
} | |
void LibST7735S::drawImage3(uint8_t x, uint8_t y, uint8_t w, uint8_t h,vector<uint8_t>* d){ | |
this->setWindow(LCD_X_OFFSET+x, LCD_Y_OFFSET+y, | |
LCD_X_OFFSET+x+w-1, LCD_Y_OFFSET+y+h-1); | |
activeRAMWrite(); | |
this->writeData_vector2(d); | |
} | |
//==[private]============================================================================ | |
void LibST7735S::setMADCTL(uint8_t MY,uint8_t MX,uint8_t MV,uint8_t ML, | |
uint8_t RGB,uint8_t MH){ | |
//MY Row Address Order | |
//MX Column Address Order | |
//MV Row/Column Exchange | |
//ML Vertical Refresh Order | |
//RGB RGB-BGR ORDER | |
//MH Horizontal Refresh Order | |
this->writeCommand(CMD_MEMORY_DATA_ACCESS_CONTROL); | |
uint8_t d = 0; | |
if(MY > 0) d += 0x80; | |
if(MX > 0) d += 0x40; | |
if(MV > 0) d += 0x20; | |
if(ML > 0) d += 0x10; | |
if(RGB > 0) d += 0x08; | |
if(MH > 0) d += 0x04; | |
this->writeData(d); | |
} | |
void LibST7735S::setWindow(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2){ | |
vector<uint8_t> tbx = {0, x1, 0, x2}; | |
vector<uint8_t> tby = {0, y1, 0, y2}; | |
this->writeCommand(CMD_COLUMN_ADRRESS_SET); | |
this->writeData_vector(&tbx); | |
this->writeCommand(CMD_ROW_ADRRESS_SET); | |
this->writeData_vector(&tby); | |
vector<uint8_t>().swap(tbx); | |
vector<uint8_t>().swap(tby); | |
} | |
void LibST7735S::setColorFormat(uint8_t color_format){ | |
switch(color_format) | |
{ default: color_format = COLOR_FORMAT_18BIT; break; | |
case COLOR_FORMAT_18BIT: break; | |
case COLOR_FORMAT_16BIT: break; | |
case COLOR_FORMAT_12BIT: break; | |
} | |
this->color_format = color_format; | |
writeCommand(CMD_INTERFACE_PIXEL_FORMAT); | |
writeData(color_format); | |
} | |
void LibST7735S::setGamma(uint8_t state){ | |
switch(state) | |
{ /* [GS_Pin = 0] Checked on hardware! */ | |
default: state = 1; break; | |
case 2: break; | |
case 4: break; | |
case 8: break; | |
} | |
this->writeCommand(CMD_GAMMA_SET); | |
this->writeData(state); | |
} | |
void LibST7735S::activeRAMWrite(){ | |
this->writeCommand(CMD_MEMORY_WRITE); | |
this->dcpin->setVal(this->HIGH); | |
} | |
void LibST7735S::writeData(int len, uint8_t *txbuf){ | |
try{ | |
this->dcpin->setVal(this->HIGH); | |
spi->transfer(len,txbuf); | |
}catch(LibSpiException e){ | |
cerr << e.getString() << endl; | |
} | |
} | |
void LibST7735S::writeData_vector(vector<uint8_t>* txbuf){ | |
try{ | |
this->dcpin->setVal(this->HIGH); | |
spi->transfer_vector(txbuf); | |
}catch(LibSpiException e){ | |
cerr << e.getString() << endl; | |
} | |
} | |
void LibST7735S::writeData_vector2(vector<uint8_t>* txbuf){ | |
try{ | |
this->dcpin->setVal(this->HIGH); | |
spi->transfer_vector2(txbuf); | |
}catch(LibSpiException e){ | |
cerr << e.getString() << endl; | |
} | |
} | |
void LibST7735S::writeData_vector3(vector<uint8_t>* txbuf){ | |
try{ | |
this->dcpin->setVal(this->HIGH); | |
spi->transfer_vector3(txbuf); | |
}catch(LibSpiException e){ | |
cerr << e.getString() << endl; | |
} | |
} | |
void LibST7735S::writeData(uint8_t data){ | |
try{ | |
this->dcpin->setVal(this->HIGH); | |
spi->transfer(data); | |
}catch(LibSpiException e){ | |
cerr << e.getString() << endl; | |
} | |
} | |
void LibST7735S::writeCommand(uint8_t cmd){ | |
try{ | |
this->dcpin->setVal(this->LOW); | |
spi->transfer(cmd); | |
}catch(LibSpiException e){ | |
cerr << e.getString() << endl; | |
} | |
} | |
void LibST7735S::HWReset(){ | |
if(this->rst == -1) return; | |
this->rstpin->setVal(this->HIGH); usleep(10*1000); //10ms | |
this->rstpin->setVal(this->LOW); usleep(10*1000); //10ms | |
this->rstpin->setVal(this->HIGH); usleep(150*1000); //150ms | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* LibST7735S.h | |
* | |
* Created on: 2018/02/05 | |
* Author: adeno | |
*/ | |
#ifndef LIBST7735S_H_ | |
#define LIBST7735S_H_ | |
#include <stdint.h> //uint8_t | |
#include <string> | |
#include <unistd.h> | |
#include <vector> | |
#include <algorithm> | |
#include "LibSpi.h" | |
#include "LibGpio.h" | |
class LibST7735S { | |
private: | |
/* SPI */ | |
LibSpi *spi; | |
int SPI_Bus; | |
int SPI_Ce; | |
int SPI_Speed; | |
uint8_t SPI_Mode; | |
/* GPIO */ | |
const static int OUTPUT = 0; | |
const static int INPUT = 1; | |
const static int HIGH = 1; | |
const static int LOW = 0; | |
/* Reset Pin */ | |
LibGpio *rstpin; | |
/* Data/Command Pin */ | |
LibGpio *dcpin; | |
/* st7735s Define*/ | |
const static uint8_t CMD_NOP = 0x00; | |
const static uint8_t CMD_SW_RESET = 0x01; | |
const static uint8_t CMD_SLEEP_OUT = 0x11; | |
const static uint8_t CMD_INVOFF = 0x20; | |
const static uint8_t CMD_INVON = 0x21; | |
const static uint8_t CMD_GAMMA_SET = 0x26; | |
const static uint8_t CMD_DISPLAY_OFF = 0x28; | |
const static uint8_t CMD_DISPLAY_ON = 0x29; | |
const static uint8_t CMD_COLUMN_ADRRESS_SET = 0x2A; | |
const static uint8_t CMD_ROW_ADRRESS_SET = 0x2B; | |
const static uint8_t CMD_MEMORY_WRITE = 0x2C; | |
const static uint8_t CMD_TEOFF = 0x34; | |
const static uint8_t CMD_TEON = 0x35; | |
const static uint8_t CMD_MEMORY_DATA_ACCESS_CONTROL = 0x36; | |
const static uint8_t CMD_INTERFACE_PIXEL_FORMAT = 0x3A; | |
const static uint8_t COLOR_FORMAT_12BIT = 0b011; | |
const static uint8_t COLOR_FORMAT_16BIT = 0b101; | |
const static uint8_t COLOR_FORMAT_18BIT = 0b110; | |
/* st7735s RAW Display Type */ | |
int a0; /* Data/Command line */ | |
int rst; /* Reset line */ | |
uint8_t width; /* Currently used width */ | |
uint8_t height; /* Currently used height */ | |
uint8_t color_format; | |
void createDisplay(uint8_t width,uint8_t height,uint8_t color_format); | |
void HWReset(); | |
void setMADCTL(uint8_t MY,uint8_t MX,uint8_t MV,uint8_t ML,uint8_t RGB,uint8_t MH); | |
void setGamma(uint8_t state); | |
void setColorFormat(uint8_t color_format); | |
void setWindow(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2); | |
void activeRAMWrite(); | |
void writeData(uint8_t data); | |
void writeData(int len, uint8_t *txbuf); | |
void writeData_vector(vector<uint8_t>* txbuf); | |
void writeData_vector2(vector<uint8_t>* txbuf); | |
void writeData_vector3(vector<uint8_t>* txbuf); | |
void writeCommand(uint8_t cmd); | |
public: | |
LibST7735S(int SPI_Bus, int SPI_Ce, int SPI_Speed,uint8_t SPI_Mode,int a0, int rst,uint8_t width,uint8_t height); | |
void fillScreen(uint8_t red, uint8_t green, uint8_t blue); | |
void fillRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height,uint8_t red, uint8_t green, uint8_t blue); | |
void drawPx(uint8_t x, uint8_t y,uint8_t red, uint8_t green, uint8_t blue); | |
void drawImage(uint8_t x, uint8_t y, uint8_t w, uint8_t h,vector<char>* d); | |
void drawImage2(uint8_t x, uint8_t y, uint8_t w, uint8_t h,vector<char>* d); | |
void drawImage3(uint8_t x, uint8_t y, uint8_t w, uint8_t h,vector<uint8_t>* d); | |
virtual ~LibST7735S(); | |
}; | |
#endif /* LIBST7735S_H_ */ |
メモ
動画やGIFから連続したBMPを作成する
convert -coalesce -resize 128x128! cinemagraph.gif +adjoin SL%02d.bmp
色を24bitにする
mogrify -type truecolor SL*.bmp
参考
http://www.c-lang.net/general43/index.html
http://yoppa.org/blog/5862.html
http://cdecrement.blog.fc2.com/blog-entry-65.html