Skip to content

Commit

Permalink
ESP32-C3 integration (#178)
Browse files Browse the repository at this point in the history
  • Loading branch information
unlogisch04 committed Sep 13, 2022
1 parent 1e39fb4 commit 9d93df6
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 34 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ Firmware can work with both ESP8266 and ESP32. Please edit `defines.h` and set y
* LED will turn off when calibration is complete
* You don't have to calibrate next time you power it off, calibration values will be saved for the next use

## Infos about ESP32-C3 with direct connection to USB

The ESP32-C3 has two ways to connect the serial port. One is directly via the onboard USB CDC or via the onboard UART.
When the chip is connected to the USB CDC, the serial port shows as `USB Serial Port` in Device Manager. The SlimeVR server will currently not connect to this port.
If you want to set your WiFi credentials, you can use the PlatformIO serial console.
There you have to enter the following: `SET WIFI "SSID" "PASSWORD"`

## Uploading On Linux

Follow the instructions in this link [Platformio](https://docs.platformio.org/en/latest//faq.html#platformio-udev-rules), this should solve any permission denied errors
Expand Down
32 changes: 28 additions & 4 deletions ci/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
class Board(Enum):
SLIMEVR = "BOARD_SLIMEVR"
WROOM32 = "BOARD_WROOM32"
LOLIN_C3_MINI = "BOARD_LOLIN_C3_MINI"
ES32C3DEVKITM1 = "BOARD_ES32C3DEVKITM1"


class DeviceConfiguration:
Expand All @@ -25,10 +27,20 @@ def __init__(self, platform: str, board: Board, platformio_board: str) -> None:
self.platformio_board = platformio_board

def get_platformio_section(self) -> str:
section = dedent(f"""
[env:{self.platformio_board}]
platform = {self.platform}
board = {self.platformio_board}""")
section = f"[env:{self.platformio_board}]\n"
section += f"platform = {self.platform}\n"
section += f"board = {self.platformio_board}\n"

if self.board == Board.LOLIN_C3_MINI:
section += "build_flags = \n"
section += " ${env.build_flags}\n"
section += " -DESP32C3\n"

if self.board == Board.ES32C3DEVKITM1:
section += "build_flags = \n"
section += " ${env.build_flags}\n"
section += " -DESP32C3\n"

return section

def filename(self) -> str:
Expand Down Expand Up @@ -56,6 +68,18 @@ def build_header(self) -> str:
imu_int = "23"
imu_int2 = "25"
battery_level = "36"
elif self.board == Board.LOLIN_C3_MINI:
sda = "5"
scl = "4"
imu_int = "6"
imu_int2 = "8"
battery_level = "3"
elif self.board == Board.ES32C3DEVKITM1:
sda = "5"
scl = "4"
imu_int = "6"
imu_int2 = "7"
battery_level = "3"
else:
raise Exception(f"Unknown board: {self.board.value}")

Expand Down
11 changes: 8 additions & 3 deletions ci/devices.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@
"board": "SLIMEVR"
},
{
"platform": "espressif32 @ 4.4.0",
"platform": "espressif32 @ 5.1.1",
"platformio_board": "esp32dev",
"board": "WROOM32"
},
{
"platform": "espressif32 @ 4.4.0",
"platform": "espressif32 @ 5.1.1",
"platformio_board": "lolin_c3_mini",
"board": "SLIMEVR"
"board": "LOLIN_C3_MINI"
},
{
"platform": "espressif32 @ 5.1.1",
"platformio_board": "esp32-c3-devkitm-1",
"board": "ES32C3DEVKITM1"
}
]
54 changes: 40 additions & 14 deletions lib/i2cscan/i2cscan.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
#include "i2cscan.h"
#include "../../src/globals.h"

#ifdef ESP8266
uint8_t portArray[] = {16, 5, 4, 2, 14, 12, 13};
uint8_t portExclude[] = {LED_PIN};
String portMap[] = {"D0", "D1", "D2", "D4", "D5", "D6", "D7"};
// ESP32C3 has not as many ports as the ESP32
#elif defined(ESP32C3)
uint8_t portArray[] = {2, 3, 4, 5, 6, 7, 8, 9, 10};
uint8_t portExclude[] = {18, 19, 20, 21, LED_PIN};
String portMap[] = {"2", "3", "4", "5", "6", "7", "8", "9", "10"};
#elif defined(ESP32)
uint8_t portArray[] = {4, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 25, 26, 27, 32, 33};
String portMap[] = {"4", "13", "14", "15", "16", "17", "18", "19", "21", "22", "23", "25", "26", "27", "32", "33"};
uint8_t portExclude[] = {LED_PIN};
#endif

namespace I2CSCAN
Expand Down Expand Up @@ -33,7 +41,7 @@ namespace I2CSCAN
{
for (uint8_t j = 0; j < sizeof(portArray); j++)
{
if (i != j)
if ((i != j) && !inArray(portArray[i], portExclude, sizeof(portExclude)) && !inArray(portArray[j], portExclude, sizeof(portExclude)))
{
if(checkI2C(i, j))
found = true;
Expand All @@ -43,12 +51,38 @@ namespace I2CSCAN
if(!found) {
Serial.println("[ERR] I2C: No I2C devices found");
}

#if ESP32
Wire.end();
#endif

// Reset the I2C interface back to it's original values
Wire.begin(static_cast<int>(PIN_IMU_SDA), static_cast<int>(PIN_IMU_SCL));
}

bool inArray(uint8_t value, uint8_t* array, size_t arraySize)
{
for (size_t i = 0; i < arraySize; i++)
{
if (value == array[i])
{
return true;
}
}

return false;
}

bool checkI2C(uint8_t i, uint8_t j)
{
bool found = false;
Wire.begin(portArray[i], portArray[j]);

#if ESP32
Wire.end();
#endif

Wire.begin((int)portArray[i], (int)portArray[j]);

byte error, address;
int nDevices;
nDevices = 0;
Expand All @@ -62,23 +96,15 @@ namespace I2CSCAN

if (error == 0)
{
Serial.print("[DBG] I2C (@ " + portMap[i] + " : " + portMap[j] + "): ");
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");

Serial.printf("[DBG] I2C (@ %s(%d) : %s(%d)): I2C device found at address 0x%02x !\n",
portMap[i].c_str(), portArray[i], portMap[j].c_str(), portArray[j], address);
nDevices++;
found = true;
}
else if (error == 4)
{
Serial.print("[ERR] I2C (@ " + portMap[i] + " : " + portMap[j] + "): ");
Serial.print("Unknow error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
Serial.printf("[ERR] I2C (@ %s(%d) : %s(%d)): Unknow error at address 0x%02x\n",
portMap[i].c_str(), portArray[i], portMap[j].c_str(), portArray[j], address);
}
}
return found;
Expand Down
1 change: 1 addition & 0 deletions lib/i2cscan/i2cscan.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace I2CSCAN {
bool isI2CExist(uint8_t addr);
uint8_t pickDevice(uint8_t addr1, uint8_t addr2, bool scanIfNotFound);
int clearBus(uint8_t SDA, uint8_t SCL);
boolean inArray(uint8_t value, uint8_t* arr, size_t arrSize);
}

#endif // _I2CSCAN_H_
19 changes: 18 additions & 1 deletion platformio-tools.ini
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,22 @@ platform = espressif32@4.4.0
board = esp32dev

[env:BOARD_LOLIN_C3_MINI]
platform = espressif32@4.4.0
platform = espressif32@5.1.1
build_flags =
${env.build_flags}
-DESP32C3
board = lolin_c3_mini

[env:BOARD_BEETLE32C3]
platform = espressif32@5.1.1
build_flags =
${env.build_flags}
-DESP32C3
board = dfrobot_beetle_esp32c3

[env:BOARD_ES32C3DEVKITM1]
platform = espressif32 @5.1.1
build_flags =
${env.build_flags}
-DESP32C3
board = esp32-c3-devkitm-1
24 changes: 18 additions & 6 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,25 @@ upload_speed = 921600

; Uncomment below if you want to build for esp32
; Check your board name at https://docs.platformio.org/en/latest/platforms/espressif32.html#boards
; [env:esp32]
; platform = espressif32 @ 4.4.0
; board = esp32dev
;[env:esp32]
;platform = espressif32 @ 5.1.1
;board = esp32dev
; Comment out this line below if you have any trouble uploading the firmware - and if it has a CP2102 on it (a square chip next to the usb port): change to 3000000 (3 million) for even faster upload speed
; upload_speed = 921600
;upload_speed = 921600

; If you want to use a ESP32C3, you can use this (experimental)
; Check your board name at https://docs.platformio.org/en/latest/platforms/espressif32.html#boards
; There are 2 main Boardtypes:
; 1. Boards that use a USB 2 Serial Chipset ( esp32-c3-devkitm-1, ttgo-t-oi-plus )
; 2. Boards that relay on the USB interface of the ESP32C3 ( lolin_c3_mini , dfrobot_beetle_esp32c3)
; On this board there are 2 type some of them need to have set the build flag (menuconfig)
; -DARDUINO_USB_MODE=1
; -DARDUINO_USB_CDC_ON_BOOT=1

; If you want to use a esp32c3, you can use this (experimental)
;[env:esp32c3]
;platform = espressif32 @ 4.4.0
;platform = espressif32 @ 5.1.1
;build_flags =
; ${env.build_flags}
; -DESP32C3
;board = lolin_c3_mini

2 changes: 2 additions & 0 deletions src/consts.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
#define BOARD_ESP01 8
#define BOARD_SLIMEVR 9
#define BOARD_LOLIN_C3_MINI 10
#define BOARD_BEETLE32C3 11
#define BOARD_ES32C3DEVKITM1 12

#define BAT_EXTERNAL 1
#define BAT_INTERNAL 2
Expand Down
22 changes: 19 additions & 3 deletions src/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,27 @@
// #define LED_PIN 2
// #define LED_INVERTED false
#elif BOARD == BOARD_LOLIN_C3_MINI
#define PIN_IMU_SDA 10
#define PIN_IMU_SCL 8
#define PIN_IMU_SDA 5
#define PIN_IMU_SCL 4
#define PIN_IMU_INT 6
#define PIN_IMU_INT_2 8
#define PIN_BATTERY_LEVEL 3
#define LED_PIN 7
// #define LED_INVERTED false
#elif BOARD == BOARD_BEETLE32C3
#define PIN_IMU_SDA 8
#define PIN_IMU_SCL 9
#define PIN_IMU_INT 6
#define PIN_IMU_INT_2 7
#define PIN_BATTERY_LEVEL 3
// #define LED_PIN 2
#define LED_PIN 10
#define LED_INVERTED false
#elif BOARD == BOARD_ES32C3DEVKITM1
#define PIN_IMU_SDA 5
#define PIN_IMU_SCL 4
#define PIN_IMU_INT 6
#define PIN_IMU_INT_2 7
#define PIN_BATTERY_LEVEL 3
#define LED_PIN LED_OFF // RGB LED Protocol would need to be implementetet did not brother for the test, because the board ideal for tracker ifself
// #define LED_INVERTED false
#endif
18 changes: 15 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,18 @@ BatteryMonitor battery;
void setup()
{
Serial.begin(serialBaudRate);

#ifdef ESP32C3
// Wait for the Computer to be able to connect.
delay(2000);
#endif

Serial.println();
Serial.println();
Serial.println();

logger.info("SlimeVR v" FIRMWARE_VERSION " starting up...");

//wifi_set_sleep_type(NONE_SLEEP_T);

statusManager.setStatus(SlimeVR::Status::LOADING, true);

ledManager.setup();
Expand All @@ -71,7 +75,15 @@ void setup()
// Do it only for MPU, cause reaction of BNO to this is not investigated yet
#endif
// join I2C bus
Wire.begin(PIN_IMU_SDA, PIN_IMU_SCL);

#if ESP32
// For some unknown reason the I2C seem to be open on ESP32-C3 by default. Let's just close it before opening it again. (The ESP32-C3 only has 1 I2C.)
Wire.end();
#endif

// using `static_cast` here seems to be better, because there are 2 similar function signatures
Wire.begin(static_cast<int>(PIN_IMU_SDA), static_cast<int>(PIN_IMU_SCL));

#ifdef ESP8266
Wire.setClockStretchLimit(150000L); // Default stretch limit 150mS
#endif
Expand Down

0 comments on commit 9d93df6

Please sign in to comment.