在 ESP32 S2上使用 USB Host 模块

2022-03-273.7万
精华项目
AI 快速预览详细 收起
本文介绍了在 ESP32 S2 Saola 开发板上使用 USB Host 模块的配置与调试方法。首先,通过修改 SPI.cpp 文件解决了 SPI 工作不正常的问题。接着,对 USB Host Shield 库文件进行了多处修改,包括引脚配置和降频设置。最后,通过 USBHIDBootMouse.ino 进行了测试,成功实现了 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文件中的如下内容:
  1. #if CONFIG_IDF_TARGET_ESP32
  2. //LabZDebug_Start
  3. #if CONFIG_IDF_TARGET_ESP32S2
  4.         SPIClass SPI(HSPI);
  5. #else
  6.         SPIClass SPI(VSPI);
  7. #endif
  8. //LabZDebug_End
  9. #else
  10. SPIClass SPI(FSPI);
  11. #endif
复制代码

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

  1. #elif defined(ESP32)
  2. //LABZDebug typedef SPi< P18, P23, P19, P5 > spi;
  3. //LABZDebug_Start
  4.            //SCK  MISO MOSI SS
  5. typedef SPi< P10, P21, P19, P13 > spi;
  6. //LABZDebug_End
  7. #elif defined(ARDUINO_NRF52840_FEATHER)
复制代码

1.2 给出SPI需要引脚编号才能正确的进行SPI初始化:
  1. #elif defined(SPI_HAS_TRANSACTION)
  2.         static void init() {
  3.                 //LABZDebug USB_SPI.begin(); // The SPI library with transaction will take care of setting up the pins - settings is set in beginTransaction()
  4.                                                             //LABZDebug_Start
  5.                                                                             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()
  6.                                                             //LABZDebug_End
  7.                 SPI_SS::SetDirWrite();
  8.                 SPI_SS::Set();
  9.         }
  10. #elif defined(STM32F4)
复制代码

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

2      USB_Host_Shield_Library_2.0\UsbCore.h 这里给出用到的SS和 INT Pin编号
  1. #elif defined(ESP32)
  2. //LABZDebug typedef MAX3421e<P5, P17> MAX3421E; // ESP32 boards
  3. //LABZDebug_Start
  4.                // SS  INT
  5. typedef MAX3421e<P13, P5> MAX3421E; // ESP32 boards
  6. //LABZDebug_End
  7. #elif (defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__))
  8. typedef MAX3421e<Pb4, Pb3> MAX3421E; // Sanguino
复制代码

3.USB_Host_Shield_Library_2.0\avrpins.h 这里主要是声明前面用到的PXX 的定义否则编译会出错

  1. MAKE_PIN(P3, 3); // RX0
  2. //LABZDebug_Start
  3. MAKE_PIN(P4, 4);   // INT
  4. MAKE_PIN(P13, 13);   // CLK
  5. MAKE_PIN(P26, 26);   // SS
  6. //LABZDebug_End
  7. MAKE_PIN(P21, 21); // SDA
复制代码

之后使用 USBHIDBootMouse.ino 进行测试:


  1. #include <hidboot.h>
  2. #include <usbhub.h>
  3. // Satisfy the IDE, which needs to see the include statment in the ino too.
  4. #ifdef dobogusinclude
  5. #include <spi4teensy3.h>
  6. #endif
  7. #include <SPI.h>
  8. class MouseRptParser : public MouseReportParser
  9. {
  10. protected:
  11.                void OnMouseMove        (MOUSEINFO *mi);
  12.                void OnLeftButtonUp      (MOUSEINFO *mi);
  13.                void OnLeftButtonDown               (MOUSEINFO *mi);
  14.                void OnRightButtonUp    (MOUSEINFO *mi);
  15.                void OnRightButtonDown             (MOUSEINFO *mi);
  16.                void OnMiddleButtonUp                (MOUSEINFO *mi);
  17.                void OnMiddleButtonDown          (MOUSEINFO *mi);
  18. };
  19. void MouseRptParser::OnMouseMove(MOUSEINFO *mi)
  20. {
  21.     Serial.print("dx=");
  22.     Serial.print(mi->dX, DEC);
  23.     Serial.print(" dy=");
  24.     Serial.println(mi->dY, DEC);
  25. };
  26. void MouseRptParser::OnLeftButtonUp   (MOUSEINFO *mi)
  27. {
  28.     Serial.println("L Butt Up");
  29. };
  30. void MouseRptParser::OnLeftButtonDown            (MOUSEINFO *mi)
  31. {
  32.     Serial.println("L Butt Dn");
  33. };
  34. void MouseRptParser::OnRightButtonUp               (MOUSEINFO *mi)
  35. {
  36.     Serial.println("R Butt Up");
  37. };
  38. void MouseRptParser::OnRightButtonDown          (MOUSEINFO *mi)
  39. {
  40.     Serial.println("R Butt Dn");
  41. };
  42. void MouseRptParser::OnMiddleButtonUp            (MOUSEINFO *mi)
  43. {
  44.     Serial.println("M Butt Up");
  45. };
  46. void MouseRptParser::OnMiddleButtonDown      (MOUSEINFO *mi)
  47. {
  48.     Serial.println("M Butt Dn");
  49. };
  50. USB     Usb;
  51. USBHub     Hub(&Usb);
  52. HIDBoot<USB_HID_PROTOCOL_MOUSE>    HidMouse(&Usb);
  53. MouseRptParser                               Prs;
  54. void setup()
  55. {
  56.     Serial.begin( 115200 );
  57. #if !defined(__MIPSEL__)
  58.     while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
  59. #endif
  60.     Serial.println("Start");
  61.     if (Usb.Init() == -1)
  62.         Serial.println("OSC did not start.");
  63.     delay( 200 );
  64.     HidMouse.SetReportParser(0, &Prs);
  65. }
  66. void loop()
  67. {
  68.   Usb.Task();
  69. }
复制代码

在 ESP32 S2上使用 USB Host 模块图1
运行结果如下:
在 ESP32 S2上使用 USB Host 模块图2
关于 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 Host


创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(0)
- 没有更多了 -