zoologist 发表于 2022-3-27 11:35:53

在 ESP32 S2上使用 USB Host 模块

这次实验在 ESP32 S2 Saola 开发板上使用前面设计的MicroUSB Host【参考1】。
首先遇到的问题是:ESP32S2 的 SPI 在 Arduino 环境下工作不正常(对于这个问题的分析请参阅【参考2】)。为此,我们需要直接修改 位于 C:\Users\用户名\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.1\libraries\SPI\src\SPI.cpp文件中的如下内容:
#if CONFIG_IDF_TARGET_ESP32

//LabZDebug_Start

#if CONFIG_IDF_TARGET_ESP32S2

      SPIClass SPI(HSPI);

#else

      SPIClass SPI(VSPI);

#endif

//LabZDebug_End

#else

SPIClass SPI(FSPI);

#endif
接下来修改 USB Host Shield 库文件:1.   USB_Host_Shield_Library_2.0\usbhost.h 这个文件有下面3个地方需要修改:1.1这里给出用到的 SCK/MISO/MOSI/SS Pin的编号
#elif defined(ESP32)

//LABZDebug typedef SPi< P18, P23, P19, P5 > spi;

//LABZDebug_Start

         //SCKMISO MOSI SS

typedef SPi< P10, P21, P19, P13 > spi;

//LABZDebug_End

#elif defined(ARDUINO_NRF52840_FEATHER)
1.2 给出SPI需要引脚编号才能正确的进行SPI初始化:
#elif defined(SPI_HAS_TRANSACTION)

      static void init() {

                //LABZDebug USB_SPI.begin(); // The SPI library with transaction will take care of setting up the pins - settings is set in beginTransaction()

                                                            //LABZDebug_Start

                                                                            USB_SPI.begin(10,21,19,13); // The SPI library with transaction will take care of setting up the pins - settings is set in beginTransaction()

                                                            //LABZDebug_End

                SPI_SS::SetDirWrite();

                SPI_SS::Set();

      }

#elif defined(STM32F4)
1.3降低速度(Max3421e最高支持26Mhz,但是因为 ESP32无法分频出26M,所以实际上SPI会以是20M速度工作。但是因为这次实验都是排线,所以频率高了之后会出现通讯错误的问题,为此需要进行降频)到4Mhz。将文件中      //LABZDebug USB_SPI.beginTransaction(SPISettings(26000000, MSBFIRST, SPI_MODE0)); // The MAX3421E can handle up to 26MHz, use MSB First and SPI mode 0

                     //LABZDebug_Start

                     USB_SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));

                     //LABZDebug_End


2      USB_Host_Shield_Library_2.0\UsbCore.h 这里给出用到的SS和 INT Pin编号
#elif defined(ESP32)

//LABZDebug typedef MAX3421e<P5, P17> MAX3421E; // ESP32 boards

//LABZDebug_Start

               // SSINT

typedef MAX3421e<P13, P5> MAX3421E; // ESP32 boards

//LABZDebug_End

#elif (defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__))

typedef MAX3421e<Pb4, Pb3> MAX3421E; // Sanguino


3.USB_Host_Shield_Library_2.0\avrpins.h 这里主要是声明前面用到的PXX 的定义否则编译会出错
MAKE_PIN(P3, 3); // RX0

//LABZDebug_Start

MAKE_PIN(P4, 4);   // INT

MAKE_PIN(P13, 13);   // CLK

MAKE_PIN(P26, 26);   // SS

//LABZDebug_End

MAKE_PIN(P21, 21); // SDA
之后使用 USBHIDBootMouse.ino 进行测试:

#include <hidboot.h>

#include <usbhub.h>



// Satisfy the IDE, which needs to see the include statment in the ino too.

#ifdef dobogusinclude

#include <spi4teensy3.h>

#endif

#include <SPI.h>



class MouseRptParser : public MouseReportParser

{

protected:

               void OnMouseMove      (MOUSEINFO *mi);

               void OnLeftButtonUp      (MOUSEINFO *mi);

               void OnLeftButtonDown               (MOUSEINFO *mi);

               void OnRightButtonUp    (MOUSEINFO *mi);

               void OnRightButtonDown             (MOUSEINFO *mi);

               void OnMiddleButtonUp                (MOUSEINFO *mi);

               void OnMiddleButtonDown          (MOUSEINFO *mi);

};

void MouseRptParser::OnMouseMove(MOUSEINFO *mi)

{

    Serial.print("dx=");

    Serial.print(mi->dX, DEC);

    Serial.print(" dy=");

    Serial.println(mi->dY, DEC);

};

void MouseRptParser::OnLeftButtonUp   (MOUSEINFO *mi)

{

    Serial.println("L Butt Up");

};

void MouseRptParser::OnLeftButtonDown            (MOUSEINFO *mi)

{

    Serial.println("L Butt Dn");

};

void MouseRptParser::OnRightButtonUp               (MOUSEINFO *mi)

{

    Serial.println("R Butt Up");

};

void MouseRptParser::OnRightButtonDown          (MOUSEINFO *mi)

{

    Serial.println("R Butt Dn");

};

void MouseRptParser::OnMiddleButtonUp            (MOUSEINFO *mi)

{

    Serial.println("M Butt Up");

};

void MouseRptParser::OnMiddleButtonDown      (MOUSEINFO *mi)

{

    Serial.println("M Butt Dn");

};



USB   Usb;

USBHub   Hub(&Usb);

HIDBoot<USB_HID_PROTOCOL_MOUSE>    HidMouse(&Usb);



MouseRptParser                               Prs;



void setup()

{

    Serial.begin( 115200 );

#if !defined(__MIPSEL__)

    while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection

#endif

    Serial.println("Start");



    if (Usb.Init() == -1)

      Serial.println("OSC did not start.");



    delay( 200 );



    HidMouse.SetReportParser(0, &Prs);

}



void loop()

{

Usb.Task();

}

运行结果如下:
关于 USB Host Shield 调试建议如下:1.   首先跑 board_qc.ino 确定SPI连接是否正确。如果一直有问题,那么是 SPI 不通,需要研究MOSI信号是否正常发送;如果 MOSI/SCLK 都正常但是没有 MOISO 回复,那么请检查 RESET 是否为高;2.   接下来跑USBHIDBootMouse.ino代码测试,如果有问题,应该是 INT Pin 设置的错误;3.   如果有线鼠标无法使用,那么可以实验无线鼠标,因为前者要求的功耗比较高,可能你从开发板中拉出来的5V供电不足。
参考:1.   https://mc.dfrobot.com.cn/thread-312057-1-1.html做一个MicroUSB Host2.   https://www.arduino.cn/thread-106240-1-1.htmlESP32 S2 的 SPI

页: [1]
查看完整版本: 在 ESP32 S2上使用 USB Host 模块