ビットバンギングによるSPI通信の実装(XIAO Seeed RP2040)

背景

ビットバンギング手法を用いて、ソフトウェアから直接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
 
 ```

プライバシーポリシー |ページトップへ

`