背景
ビットバンギング手法を用いて、ソフトウェアから直接GPIOを操作し、SPI通信をエミュレートします。
(Emulate SPI communication by directly manipulating GPIO in software using bit-banging techniques.)
2月17日に、e-Paperをマイコン(XIAO Seeed RP2040)で動作させました。
その際、SPI通信には専用ピン(MOSIピンとSCKピン)を使用していました。
今回、これらの機能を任意のデジタルピンに割り当てられるようにするため、ビットバンギング手法を用いて実装してみました。
ソース変更
今回のメイン変更点 SPI通信でのビットバンギング手法による、通信
void EpdIf::BitBangingSpiTransfer(unsigned char data){ for (int i = 7; i >= 0; i--) { // Set MOSI to the current bit if (data & (1 << i)) digitalWrite(MOSI_PIN, HIGH); else digitalWrite(MOSI_PIN, LOW); // Toggle SCK (rising edge) digitalWrite(SCK_PIN, HIGH); // Toggle SCK (Falling edge) // delay(1); // Hold clock high digitalWrite(SCK_PIN, LOW); // delay(1); // Hold clock low } }
epd2in9_V2.cpp
diff --git a/epd2in9_V2.cpp b/epd2in9_V2.cpp index 04ba86b..b20b188 100644 --- a/epd2in9_V2.cpp +++ b/epd2in9_V2.cpp @@ -244,7 +244,8 @@ int Epd::Init_4Gray() { void Epd::SendCommand(unsigned char command) { DigitalWrite(dc_pin, LOW); DigitalWrite(cs_pin, LOW); - Spi.Transfer(command); + //for bit banging + Spi2Transfer(command); DigitalWrite(cs_pin, HIGH); } @@ -254,7 +255,8 @@ void Epd::SendCommand(unsigned char command) { void Epd::SendData(unsigned char data) { DigitalWrite(dc_pin, HIGH); DigitalWrite(cs_pin, LOW); - Spi.Transfer(data); + //for bit banging + Spi2Transfer(data);^M DigitalWrite(cs_pin, HIGH); }
epd2in9_V2.ino
diff --git a/epd2in9_V2.ino b/epd2in9_V2.ino index afe2b02..8622e4d 100644 --- a/epd2in9_V2.ino +++ b/epd2in9_V2.ino @@ -24,7 +24,8 @@ * THE SOFTWARE. */ -#include <SPI.h> +//for bit banging +// #include <SPI.h> #include "epd2in9_V2.h" #include "epdpaint.h" #include "imagedata.h" @@ -82,40 +83,40 @@ void setup() { paint.Clear(UNCOLORED); Serial.print("paint.DrawStringAt \n\r"); paint.DrawStringAt(0, 40, "Hello world!", &Font20, COLORED); epd.SetFrameMemory(paint.GetImage(), 0, 10, paint.GetWidth(), paint.GetHeight ()); Serial.print("epd.DisplayFrame \n\r"); epd.DisplayFrame();
epdif.cpp
diff --git a/epdif.cpp b/epdif.cpp index b1f89c9..8956563 100644 --- a/epdif.cpp +++ b/epdif.cpp @@ -26,8 +26,8 @@ */ #include "epdif.h" -#include <SPI.h> - +//for bit banging +// #include <SPI.h> EpdIf::EpdIf() { }; @@ -46,23 +46,48 @@ void EpdIf::DelayMs(unsigned int delaytime) { delay(delaytime); } -void EpdIf::SpiTransfer(unsigned char data) { +//for bit banging +void EpdIf::Spi2Transfer(unsigned char data) { digitalWrite(CS_PIN, LOW); - SPI.transfer(data); + BitBangingSpiTransfer(data); digitalWrite(CS_PIN, HIGH); } +//for bit banging +void EpdIf::BitBangingSpiTransfer(unsigned char data){ + for (int i = 7; i >= 0; i--) { + // Set MOSI to the current bit + if (data & (1 << i)) + digitalWrite(MOSI_PIN, HIGH); + else + digitalWrite(MOSI_PIN, LOW); + + // Toggle SCK (rising edge) + digitalWrite(SCK_PIN, HIGH); + // Toggle SCK (Falling edge) + // delay(1); // Hold clock high + digitalWrite(SCK_PIN, LOW); + // delay(1); // Hold clock low + } +} + + int EpdIf::IfInit(void) { pinMode(CS_PIN, OUTPUT); pinMode(RST_PIN, OUTPUT); pinMode(DC_PIN, OUTPUT); - pinMode(BUSY_PIN, INPUT); + pinMode(BUSY_PIN, INPUT); + + //for bit banging + pinMode(SCK_PIN, OUTPUT); + pinMode(MOSI_PIN, OUTPUT); pinMode(PWR_PIN, OUTPUT); DigitalWrite(PWR_PIN, 1); - SPI.begin(); - SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0)); + //for bit banging + // SPI.begin(); + // SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0)); return 0; }
epdif.h
diff --git a/epdif.h b/epdif.h index 1679bed..094eae1 100644 --- a/epdif.h +++ b/epdif.h @@ -36,12 +36,18 @@ // #define CS_PIN 10 // #define BUSY_PIN 7 // #define PWR_PIN 6 + +// RP-2040 #define RST_PIN D2 #define DC_PIN D3 #define CS_PIN D4 #define BUSY_PIN D5 #define PWR_PIN D6 +//for bit banging +#define MOSI_PIN D10 +#define SCK_PIN D8 + class EpdIf { public: EpdIf(void); @@ -51,7 +57,10 @@ public: static void DigitalWrite(int pin, int value); static int DigitalRead(int pin); static void DelayMs(unsigned int delaytime); - static void SpiTransfer(unsigned char data); + //for bit banging + // static void SpiTransfer(unsigned char data); + static void Spi2Transfer(unsigned char data); + static void BitBangingSpiTransfer(unsigned char data); }; #endif ```