はじめに
Amazonで売っている小型のOLEDディスプレイをPSoC5LPで動かしました。
Arduinoで動かしてもよかったのですが、ライブラリを使うとどうしてもメモリが足りなかったのでPSoCで使いたい!
ということでちょっと調べてやってみました。
githubにあるライブラリを使ってPSoC4で動かしてから、PSoC5用に改良していきます。
OLEDについて
今回使ったのは128x32のサイズのもの
Amazonで500円ぐらいで手に入ります。
PSoC4で動かす
githubにSSD1306をPSoC4PioneerKit用に変更したものを公開しているのでそれを使います。
このライブラリはAdafruitグラフィックスライブラリをPSoC用に変更したものになっています。
PSoC4PioneerKitで使うならばそのままでいいのですが、今回はPSoC5で使いたいので移植する必要があります。
PSoC5LP用に改良する
PSoC4にはSerial Communication Block (SCB)というコンポーネントが乗っていて、そいつをUARTやSPIやI2Cのモジュールとして使っています。
一方PSoC5にはI2C単体のモジュールがあるのでSCBの変わりにそれを使います。
とはモジュールの仕様が多少異なっているため手を加えなければなりません。
IssueにはPSoC5での実装についてコメントがありました。
For PSoC 5 use byte to byte transfer instead of MasterWriteBuf. PSoC 5 API can send only 256 bytes per one MasterWriteBuf call.
PSoC5のAPIでは一度に256byteしか送信できないからbyte to byteを使え!ってことですね。
データシートを見ると
SCBは
uint32 SCB_I2CMasterWriteBuf(uint32 slaveAddress, uint8 * wrData, uint32 cnt , uint32 mode)
I2Cは
uint8 I2C_MasterReadBuf(uint8 slaveAddress, uint8 * rdData, uint8 cnt , uint8 mode)
となっていてPSoC5のAPIでは一度に256byteしか送信できないことがわかります。
そこでPSoC5ではuint8 I2C_MasterWriteByte(uint8 theByte)
を使って手動で送るように変更してやります。
具体的にはssd1306.cのstatic uint32 display_write_buf関数内の
I2COLED_I2CMasterWriteBuf(_i2caddr, buf, size, I2COLED_I2C_MODE_COMPLETE_XFER);
while( 0u == (I2COLED_I2CMasterStatus() & I2COLED_I2C_MSTAT_WR_CMPLT) );
の部分を
status = I2COLED_MasterSendStart(_i2caddr, I2C_WRITE_XFER_MODE);
if(I2COLED_MSTR_NO_ERROR == status)
{
for(i = 0; i<size; i++)
{
status = I2COLED_MasterWriteByte(buf[i]);
if(status != I2COLED_MSTR_NO_ERROR)
{
break;
}
}
}
I2COLED_MasterSendStop();
と変更してやります。
完成
PSoC5でAmazonにあるSSD1306のOLED動いた pic.twitter.com/LAWXQNx09K
— ringo (@Malus_Mill_) 2017年9月18日
sampleを動かしているところです。
以上の変更でPSoC5でSSD1306を使うことができます。
終わりに
当初の目的はロガーの表示機がほしいなと思って作り始めたけど、Arduinoじゃメモリ足りないしなぁ。。。ということでやってみましたが、キャラクタ液晶と違ってなんでも表示できるのは楽しいですね。
今後は日本語フォントの実装とかできたらいいなと思います。