From 4ed68f630b9c9b0e26b2a48f14eae1627b7e2372 Mon Sep 17 00:00:00 2001 From: Nathan Date: Sat, 1 Feb 2020 00:35:36 -0700 Subject: [PATCH] Added v2 firmware w/ switch support see updated readme for new build instructions --- Firmware/BlueCubeModv2/Makefile | 8 + Firmware/BlueCubeModv2/main/component.mk | 4 + Firmware/BlueCubeModv2/main/main.c | 880 +++++++++++++++++++++++ Firmware/BlueCubeModv2/sdkconfig | 705 ++++++++++++++++++ PCB/BlueCubeModRev2Schematics.pdf | Bin 0 -> 32759 bytes PCB/Eagle/BlueCubeModR2.brd | 63 +- PCB/Eagle/BlueCubeModR2.sch | 39 +- README.md | 14 +- 8 files changed, 1660 insertions(+), 53 deletions(-) create mode 100755 Firmware/BlueCubeModv2/Makefile create mode 100755 Firmware/BlueCubeModv2/main/component.mk create mode 100755 Firmware/BlueCubeModv2/main/main.c create mode 100644 Firmware/BlueCubeModv2/sdkconfig create mode 100644 PCB/BlueCubeModRev2Schematics.pdf diff --git a/Firmware/BlueCubeModv2/Makefile b/Firmware/BlueCubeModv2/Makefile new file mode 100755 index 0000000..c27ad80 --- /dev/null +++ b/Firmware/BlueCubeModv2/Makefile @@ -0,0 +1,8 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := BlueCubeModv2 + +include $(IDF_PATH)/make/project.mk diff --git a/Firmware/BlueCubeModv2/main/component.mk b/Firmware/BlueCubeModv2/main/component.mk new file mode 100755 index 0000000..3277c9f --- /dev/null +++ b/Firmware/BlueCubeModv2/main/component.mk @@ -0,0 +1,4 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) \ No newline at end of file diff --git a/Firmware/BlueCubeModv2/main/main.c b/Firmware/BlueCubeModv2/main/main.c new file mode 100755 index 0000000..88422c9 --- /dev/null +++ b/Firmware/BlueCubeModv2/main/main.c @@ -0,0 +1,880 @@ +// +// BlueCubeMod Firmware +// +// +// Created by Nathan Reeves 2019 +// + +#include "esp_log.h" +#include "esp_hidd_api.h" +#include "esp_bt_main.h" +#include "esp_bt_device.h" +#include "esp_bt.h" +#include "esp_err.h" +#include "nvs.h" +#include "nvs_flash.h" +#include "esp_gap_bt_api.h" +#include +#include +#include +#include "esp_timer.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" + +#include "driver/gpio.h" +#include "driver/rmt.h" +#include "driver/periph_ctrl.h" +#include "soc/rmt_reg.h" + + + +#define LED_GPIO 25 +#define PIN_SEL (1ULL<controller command: 0100 0000 0000 0011 0000 0010 + + items[0].duration0 = 3; + items[0].level0 = 0; + items[0].duration1 = 1; + items[0].level1 = 1; + items[1].duration0 = 1; + items[1].level0 = 0; + items[1].duration1 = 3; + items[1].level1 = 1; + int j; + for(j = 0; j < 12; j++) { + items[j+2].duration0 = 3; + items[j+2].level0 = 0; + items[j+2].duration1 = 1; + items[j+2].level1 = 1; + } + items[14].duration0 = 1; + items[14].level0 = 0; + items[14].duration1 = 3; + items[14].level1 = 1; + items[15].duration0 = 1; + items[15].level0 = 0; + items[15].duration1 = 3; + items[15].level1 = 1; + for(j = 0; j < 8; j++) { + items[j+16].duration0 = 3; + items[j+16].level0 = 0; + items[j+16].duration1 = 1; + items[j+16].level1 = 1; + } + items[24].duration0 = 1; + items[24].level0 = 0; + items[24].duration1 = 3; + items[24].level1 = 1; + +} + +//RMT Receiver Init +rmt_config_t rmt_rx; +static void rmt_rx_init() +{ + rmt_rx.channel = RMT_RX_CHANNEL; + rmt_rx.gpio_num = RMT_RX_GPIO_NUM; + rmt_rx.clk_div = RMT_CLK_DIV; + rmt_rx.mem_block_num = 4; + rmt_rx.rmt_mode = RMT_MODE_RX; + rmt_rx.rx_config.idle_threshold = rmt_item32_tIMEOUT_US / 10 * (RMT_TICK_10_US); + rmt_config(&rmt_rx); +} + +//Polls controller and formats response +//GameCube Controller Protocol: http://www.int03.co.uk/crema/hardware/gamecube/gc-control.html +static void get_buttons() +{ + ESP_LOGI("hi", "Hello world from core %d!\n", xPortGetCoreID() ); + //button init values + uint8_t but1 = 0; + uint8_t but2 = 0; + uint8_t but3 = 0; + uint8_t dpad = 0x08;//Released + uint8_t lx = 0; + uint8_t ly = 0; + uint8_t cx = 0; + uint8_t cy = 0; + uint8_t lt = 0; + uint8_t rt = 0; + + //Sample and find calibration value for sticks + int calib_loop = 0; + int xsum = 0; + int ysum = 0; + int cxsum = 0; + int cysum = 0; + int lsum = 0; + int rsum = 0; + while(calib_loop < 5) + { + lx = 0; + ly = 0; + cx = 0; + cy = 0; + lt = 0; + rt = 0; + rmt_write_items(rmt_tx.channel, items, 25, 0); + rmt_rx_start(rmt_rx.channel, 1); + + vTaskDelay(10); + + rmt_item32_t* item = (rmt_item32_t*) (RMT_CHANNEL_MEM(rmt_rx.channel)); + if(item[33].duration0 == 1 && item[27].duration0 == 1 && item[26].duration0 == 3 && item[25].duration0 == 3) + { + + //LEFT STICK X + for(int x = 8; x > -1; x--) + { + if((item[x+41].duration0 == 1)) + { + lx += pow(2, 8-x-1); + } + } + + //LEFT STICK Y + for(int x = 8; x > -1; x--) + { + if((item[x+49].duration0 == 1)) + { + ly += pow(2, 8-x-1); + } + } + //C STICK X + for(int x = 8; x > -1; x--) + { + if((item[x+57].duration0 == 1)) + { + cx += pow(2, 8-x-1); + } + } + + //C STICK Y + for(int x = 8; x > -1; x--) + { + if((item[x+65].duration0 == 1)) + { + cy += pow(2, 8-x-1); + } + } + + //R AN + for(int x = 8; x > -1; x--) + { + if((item[x+73].duration0 == 1)) + { + rt += pow(2, 8-x-1); + } + } + + //L AN + for(int x = 8; x > -1; x--) + { + if((item[x+81].duration0 == 1)) + { + lt += pow(2, 8-x-1); + } + } + + xsum += lx; + ysum += ly; + cxsum += cx; + cysum += cy; + lsum += lt; + rsum += rt; + calib_loop++; + } + + } + + //Set Stick Calibration + lxcalib = 127-(xsum/5); + lycalib = 127-(ysum/5); + cxcalib = 127-(cxsum/5); + cycalib = 127-(cysum/5); + lcalib = 127-(lsum/5); + rcalib = 127-(rsum/5); + + + while(1) + { + but1 = 0; + but2 = 0; + but3 = 0; + dpad = 0x08; + lx = 0; + ly = 0; + cx = 0; + cy = 0; + lt = 0; + rt = 0; + + //Write command to controller + rmt_write_items(rmt_tx.channel, items, 25, 0); + rmt_rx_start(rmt_rx.channel, 1); + + vTaskDelay(6); //6ms between sample + + rmt_item32_t* item = (rmt_item32_t*) (RMT_CHANNEL_MEM(rmt_rx.channel)); + + //Check first 3 bits and high bit at index 33 + if(item[33].duration0 == 1 && item[27].duration0 == 1 && item[26].duration0 == 3 && item[25].duration0 == 3) + { + + //Button report: first item is item[25] + //0 0 1 S Y X B A + //1 L R Z U D R L + //Joystick X (8bit) + //Joystick Y (8bit) + //C-Stick X (8bit) + //C-Stick Y (8bit) + //L Trigger Analog (8/4bit) + //R Trigger Analog (8/4bit) + + if(item[32].duration0 == 1) but1 += 0x08;// A + if(item[31].duration0 == 1) but1 += 0x04;// B + if(item[30].duration0 == 1) but1 += 0x02;// X + if(item[29].duration0 == 1) but1 += 0x01;// Y + + if(item[28].duration0 == 1) but2 += 0x02;// START/PLUS + + //DPAD + if(item[40].duration0 == 1) but3 += 0x08;// L + if(item[39].duration0 == 1) but3 += 0x04;// R + if(item[38].duration0 == 1) but3 += 0x01;// D + if(item[37].duration0 == 1) but3 += 0x02;// U + + if(item[35].duration0 == 1) but1 += 0x80;// ZR + if(item[34].duration0 == 1) but3 += 0x80;// ZL + //Buttons + if(item[36].duration0 == 1) + { + but1 += 0x40;// Z + // if(but3 == 0x80) { but3 += 0x40;} + if(but2 == 0x02) { but2 = 0x01; } // Minus = Z + Start + if(but3 == 0x02) { but2 = 0x10; } // Home = Z + Up + } + + //LEFT STICK X + for(int x = 8; x > -1; x--) + { + if(item[x+41].duration0 == 1) + { + lx += pow(2, 8-x-1); + } + } + + //LEFT STICK Y + for(int x = 8; x > -1; x--) + { + if(item[x+49].duration0 == 1) + { + ly += pow(2, 8-x-1); + } + } + + //C STICK X + for(int x = 8; x > -1; x--) + { + if(item[x+57].duration0 == 1) + { + cx += pow(2, 8-x-1); + } + } + + //C STICK Y + for(int x = 8; x > -1; x--) + { + if(item[x+65].duration0 == 1) + { + cy += pow(2, 8-x-1); + } + } + + /// Analog triggers here -- Ignore for Switch :/ + /* + //R AN + for(int x = 8; x > -1; x--) + { + if(item[x+73].duration0 == 1) + { + rt += pow(2, 8-x-1); + } + } + + //L AN + for(int x = 8; x > -1; x--) + { + if(item[x+81].duration0 == 1) + { + lt += pow(2, 8-x-1); + } + }*/ + ///// + xSemaphoreTake(xSemaphore, portMAX_DELAY); + but1_send = but1; + but2_send = but2; + but3_send = but3; + lx_send = lx + lxcalib; + ly_send = ly + lycalib; + cx_send = cx + cxcalib; + cy_send = cy + cycalib; + lt_send = 0;//lt;//left trigger analog + rt_send = 0;//rt;//right trigger analog + xSemaphoreGive(xSemaphore); + }else{ + //log_info("GameCube controller read fail"); + } + + } +} +SemaphoreHandle_t xSemaphore; +bool connected = false; +int paired = 0; +TaskHandle_t SendingHandle = NULL; +TaskHandle_t BlinkHandle = NULL; +//Switch button report example // batlvl Buttons Lstick Rstick +//static uint8_t report30[] = {0x30, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +uint8_t timer = 0; +static uint8_t report30[] = { + 0x30, + 0x0, + 0x80, + 0,//but1 + 0,//but2 + 0,//but3 + 0,//Ls + 0,//Ls + 0,//Ls + 0,//Rs + 0,//Rs + 0,//Rs + 0x08 +}; + +void send_buttons() +{ + xSemaphoreTake(xSemaphore, portMAX_DELAY); + report30[1] = timer; + //buttons + report30[3] = but1_send; + report30[4] = but2_send; + report30[5] = but3_send; + //encode left stick + report30[6] = (lx_send << 4) & 0xF0; + report30[7] = (lx_send & 0xF0) >> 4; + report30[8] = ly_send; + //encode right stick + report30[9] = (cx_send << 4) & 0xF0; + report30[10] = (cx_send & 0xF0) >> 4; + report30[11] = cy_send; + xSemaphoreGive(xSemaphore); + timer+=1; + if(timer == 255) + timer = 0; + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(report30), report30); + + if(!paired) + vTaskDelay(100); + else + vTaskDelay(15); + + +} +const uint8_t hid_descriptor_gamecube[] = { + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x05, // Usage (Game Pad) + 0xA1, 0x01, // Collection (Application) + //Padding + 0x95, 0x03, // REPORT_COUNT = 3 + 0x75, 0x08, // REPORT_SIZE = 8 + 0x81, 0x03, // INPUT = Cnst,Var,Abs + //Sticks + 0x09, 0x30, // Usage (X) + 0x09, 0x31, // Usage (Y) + 0x09, 0x32, // Usage (Z) + 0x09, 0x35, // Usage (Rz) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x75, 0x08, // Report Size (8) + 0x95, 0x04, // Report Count (4) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + //DPAD + 0x09, 0x39, // Usage (Hat switch) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x07, // Logical Maximum (7) + 0x35, 0x00, // Physical Minimum (0) + 0x46, 0x3B, 0x01, // Physical Maximum (315) + 0x65, 0x14, // Unit (System: English Rotation, Length: Centimeter) + 0x75, 0x04, // Report Size (4) + 0x95, 0x01, // Report Count (1) + 0x81, 0x42, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State) + //Buttons + 0x65, 0x00, // Unit (None) + 0x05, 0x09, // Usage Page (Button) + 0x19, 0x01, // Usage Minimum (0x01) + 0x29, 0x0E, // Usage Maximum (0x0E) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x0E, // Report Count (14) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + //Padding + 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) + 0x09, 0x20, // Usage (0x20) + 0x75, 0x06, // Report Size (6) + 0x95, 0x01, // Report Count (1) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x7F, // Logical Maximum (127) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + //Triggers + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x33, // Usage (Rx) + 0x09, 0x34, // Usage (Ry) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x75, 0x08, // Report Size (8) + 0x95, 0x02, // Report Count (2) + 0x81, 0x02, + 0xc0 +}; +int hid_descriptor_gc_len = sizeof(hid_descriptor_gamecube); +///Switch Replies +static uint8_t reply02[] = {0x21, 0x01, 0x40, 0x00, 0x00, 0x00, 0xe6, 0x27, 0x78, 0xab, 0xd7, 0x76, 0x00, 0x82, 0x02, 0x03, 0x48, 0x03, 0x02, 0xD8, 0xA0, 0x1D, 0x40, 0x15, 0x66, 0x03, 0x00, 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 + , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }; +static uint8_t reply08[] = {0x21, 0x02, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 + , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }; +static uint8_t reply03[] = {0x21, 0x05, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 + , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }; +static uint8_t reply04[] = {0x21, 0x06, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x83, 0x04, 0x00, 0x6a, 0x01, 0xbb, 0x01, 0x93, 0x01, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 + , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00}; +static uint8_t reply1060[] = {0x21, 0x03, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x90, 0x10, 0x00, 0x60, 0x00, 0x00, 0x10, 0x00, 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 + , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }; +static uint8_t reply1050[] = { 0x21, 0x04, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x90, 0x10, 0x50, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 + , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }; +static uint8_t reply1080[] = {0x21, 0x04, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x90, 0x10, 0x80, 0x60, 0x00, 0x00, 0x18, 0x5e, 0x01, 0x00, 0x00, 0xf1, 0x0f, + 0x19, 0xd0, 0x4c, 0xae, 0x40, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00}; +static uint8_t reply1098[] = {0x21, 0x04, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x90, 0x10, 0x98, 0x60, 0x00, 0x00, 0x12, 0x19, 0xd0, 0x4c, 0xae, 0x40, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00}; +//User analog stick calib +static uint8_t reply1010[] = {0x21, 0x04, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x90, 0x10, 0x10, 0x80, 0x00, 0x00, 0x18, 0x00, 0x00}; +static uint8_t reply103D[] = {0x21, 0x05, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x90, 0x10, 0x3D, 0x60, 0x00, 0x00, 0x19, 0xF0, 0x07, 0x7f, 0xF0, 0x07, 0x7f, 0xF0, 0x07, 0x7f, 0xF0, 0x07, 0x7f, 0xF0, 0x07, 0x7f, 0xF0, 0x07, 0x7f, 0xF0, 0x07, 0x7f, 0xF0, 0x07, 0x7f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00}; +static uint8_t reply1020[] = {0x21, 0x04, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x90, 0x10, 0x20, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00}; +static uint8_t reply4001[] = {0x21, 0x04, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static uint8_t reply4801[] = {0x21, 0x04, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x80, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static uint8_t reply3001[] = {0x21, 0x04, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static uint8_t reply3333[] = {0x21, 0x03, 0x8E, 0x84, 0x00, 0x12, 0x01, 0x18, 0x80, 0x01, 0x18, 0x80, 0x80, 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 + , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00, 0x00 }; + + + +// sending bluetooth values every 15ms +void send_task(void* pvParameters) { + const char* TAG = "send_task"; + ESP_LOGI(TAG, "Sending hid reports on core %d\n", xPortGetCoreID() ); + while(1) + { + send_buttons(); + } +} + +// callback for notifying when hidd application is registered or not registered +void application_cb(esp_bd_addr_t bd_addr, esp_hidd_application_state_t state) { + const char* TAG = "application_cb"; + + switch(state) { + case ESP_HIDD_APP_STATE_NOT_REGISTERED: + ESP_LOGI(TAG, "app not registered"); + break; + case ESP_HIDD_APP_STATE_REGISTERED: + ESP_LOGI(TAG, "app is now registered!"); + if(bd_addr == NULL) { + ESP_LOGI(TAG, "bd_addr is null..."); + break; + } + break; + default: + ESP_LOGW(TAG, "unknown app state %i", state); + break; + } +} +//LED blink +void startBlink() +{ + while(1) { + gpio_set_level(LED_GPIO, 0); + vTaskDelay(150); + gpio_set_level(LED_GPIO, 1); + vTaskDelay(150); + gpio_set_level(LED_GPIO, 0); + vTaskDelay(150); + gpio_set_level(LED_GPIO, 1); + vTaskDelay(1000); + } + vTaskDelete(NULL); +} +// callback for hidd connection changes +void connection_cb(esp_bd_addr_t bd_addr, esp_hidd_connection_state_t state) { + const char* TAG = "connection_cb"; + + switch(state) { + case ESP_HIDD_CONN_STATE_CONNECTED: + ESP_LOGI(TAG, "connected to %02x:%02x:%02x:%02x:%02x:%02x", + bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]); + ESP_LOGI(TAG, "setting bluetooth non connectable"); + esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE); + + //clear blinking LED - solid + vTaskDelete(BlinkHandle); + BlinkHandle = NULL; + gpio_set_level(LED_GPIO, 1); + //start solid + xSemaphoreTake(xSemaphore, portMAX_DELAY); + connected = true; + xSemaphoreGive(xSemaphore); + //restart send_task + if(SendingHandle != NULL) + { + vTaskDelete(SendingHandle); + SendingHandle = NULL; + } + xTaskCreatePinnedToCore(send_task, "send_task", 2048, NULL, 2, &SendingHandle, 0); + break; + case ESP_HIDD_CONN_STATE_CONNECTING: + ESP_LOGI(TAG, "connecting"); + break; + case ESP_HIDD_CONN_STATE_DISCONNECTED: + xTaskCreate(startBlink, "blink_task", 1024, NULL, 1, &BlinkHandle); + //start blink + ESP_LOGI(TAG, "disconnected from %02x:%02x:%02x:%02x:%02x:%02x", + bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]); + ESP_LOGI(TAG, "making self discoverable"); + paired = 0; + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + xSemaphoreTake(xSemaphore, portMAX_DELAY); + connected = false; + xSemaphoreGive(xSemaphore); + break; + case ESP_HIDD_CONN_STATE_DISCONNECTING: + ESP_LOGI(TAG, "disconnecting"); + break; + default: + ESP_LOGI(TAG, "unknown connection status"); + break; + } +} + +//callback for discovering +void get_device_cb() +{ + ESP_LOGI("hi", "found a device"); +} + +// callback for when hid host requests a report +void get_report_cb(uint8_t type, uint8_t id, uint16_t buffer_size) { + const char* TAG = "get_report_cb"; + ESP_LOGI(TAG, "got a get_report request from host"); +} + +// callback for when hid host sends a report +void set_report_cb(uint8_t type, uint8_t id, uint16_t len, uint8_t* p_data) { + const char* TAG = "set_report_cb"; + ESP_LOGI(TAG, "got a report from host"); +} + +// callback for when hid host requests a protocol change +void set_protocol_cb(uint8_t protocol) { + const char* TAG = "set_protocol_cb"; + ESP_LOGI(TAG, "got a set_protocol request from host"); +} + +// callback for when hid host sends interrupt data +void intr_data_cb(uint8_t report_id, uint16_t len, uint8_t* p_data) { + const char* TAG = "intr_data_cb"; + //switch pairing sequence + if(len == 49) + { + if(p_data[10] == 2) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply02), reply02); + } + if(p_data[10] == 8) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply08), reply08); + } + if(p_data[10] == 16 && p_data[11] == 0 && p_data[12] == 96) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply1060), reply1060); + } + if(p_data[10] == 16 && p_data[11] == 80 && p_data[12] == 96) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply1050), reply1050); + } + if(p_data[10] == 3) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply03), reply03); + } + if(p_data[10] == 4) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply04), reply04); + } + if(p_data[10] == 16 && p_data[11] == 128 && p_data[12] == 96) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply1080), reply1080); + } + if(p_data[10] == 16 && p_data[11] == 152 && p_data[12] == 96) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply1098), reply1098); + } + if(p_data[10] == 16 && p_data[11] == 16 && p_data[12] == 128) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply1010), reply1010); + } + if(p_data[10] == 16 && p_data[11] == 61 && p_data[12] == 96) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply103D), reply103D); + } + if(p_data[10] == 16 && p_data[11] == 32 && p_data[12] == 96) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply1020), reply1020); + } + if(p_data[10] == 64 && p_data[11] == 1) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply4001), reply4001); + } + if(p_data[10] == 72 && p_data[11] == 1) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply4801), reply4801); + } + if(p_data[10] == 48 && p_data[11] == 1) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply3001), reply3001); + } + + if(p_data[10] == 33 && p_data[11] == 33) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply3333), reply3333); + paired = 1; + + } + if(p_data[10] == 64 && p_data[11] == 2) + { + esp_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0xa1, sizeof(reply4001), reply4001); + } + //ESP_LOGI(TAG, "got an interrupt report from host, subcommand: %d %d %d Length: %d", p_data[10], p_data[11], p_data[12], len); + } + else + { + + //ESP_LOGI("heap size:", "%d", xPortGetFreeHeapSize()); + //ESP_LOGI(TAG, "pairing packet size != 49, subcommand: %d %d %d Length: %d", p_data[10], p_data[11], p_data[12], len); + } + + +} + +// callback for when hid host does a virtual cable unplug +void vc_unplug_cb(void) { + const char* TAG = "vc_unplug_cb"; + ESP_LOGI(TAG, "host did a virtual cable unplug"); +} + +void print_bt_address() { + const char* TAG = "bt_address"; + const uint8_t* bd_addr; + + bd_addr = esp_bt_dev_get_address(); + ESP_LOGI(TAG, "my bluetooth address is %02X:%02X:%02X:%02X:%02X:%02X", + bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]); +} + +#define SPP_TAG "tag" +static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +{ + switch(event){ + case ESP_BT_GAP_DISC_RES_EVT: + ESP_LOGI(SPP_TAG, "ESP_BT_GAP_DISC_RES_EVT"); + esp_log_buffer_hex(SPP_TAG, param->disc_res.bda, ESP_BD_ADDR_LEN); + break; + case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: + ESP_LOGI(SPP_TAG, "ESP_BT_GAP_DISC_STATE_CHANGED_EVT"); + break; + case ESP_BT_GAP_RMT_SRVCS_EVT: + ESP_LOGI(SPP_TAG, "ESP_BT_GAP_RMT_SRVCS_EVT"); + ESP_LOGI(SPP_TAG, "%d", param->rmt_srvcs.num_uuids); + break; + case ESP_BT_GAP_RMT_SRVC_REC_EVT: + ESP_LOGI(SPP_TAG, "ESP_BT_GAP_RMT_SRVC_REC_EVT"); + break; + case ESP_BT_GAP_AUTH_CMPL_EVT:{ + if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { + ESP_LOGI(SPP_TAG, "authentication success: %s", param->auth_cmpl.device_name); + esp_log_buffer_hex(SPP_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN); + } else { + ESP_LOGE(SPP_TAG, "authentication failed, status:%d", param->auth_cmpl.stat); + } + break; + } + + default: + break; + } +} +void app_main() { + //GameCube Contoller reading init + rmt_tx_init(); + rmt_rx_init(); + xTaskCreatePinnedToCore(get_buttons, "gbuttons", 2048, NULL, 1, NULL, 1); + //flash LED + vTaskDelay(100); + gpio_set_level(LED_GPIO, 0); + vTaskDelay(100); + gpio_set_level(LED_GPIO, 1); + vTaskDelay(100); + gpio_set_level(LED_GPIO, 0); + vTaskDelay(100); + gpio_set_level(LED_GPIO, 1); + vTaskDelay(100); + gpio_set_level(LED_GPIO, 0); + const char* TAG = "app_main"; + esp_err_t ret; + static esp_hidd_callbacks_t callbacks; + static esp_hidd_app_param_t app_param; + static esp_hidd_qos_param_t both_qos; + + xSemaphore = xSemaphoreCreateMutex(); + + gpio_config_t io_conf; + //disable interrupt + io_conf.intr_type = GPIO_PIN_INTR_DISABLE; + //set as output mode + io_conf.mode = GPIO_MODE_OUTPUT; + //bit mask of the pins that you want to set,e.g.GPIO18/19 + io_conf.pin_bit_mask = PIN_SEL; + //disable pull-down mode + io_conf.pull_down_en = 0; + //disable pull-up mode + io_conf.pull_up_en = 0; + //configure GPIO with the given settings + gpio_config(&io_conf); + //gap_callbacks = get_device_cb; + + + app_param.name = "BlueCubeMod"; + app_param.description = "BlueCubeMod Example"; + app_param.provider = "ESP32"; + app_param.subclass = 0x8; + app_param.desc_list = hid_descriptor_gamecube; + app_param.desc_list_len = hid_descriptor_gc_len; + memset(&both_qos, 0, sizeof(esp_hidd_qos_param_t)); + + callbacks.application_state_cb = application_cb; + callbacks.connection_state_cb = connection_cb; + callbacks.get_report_cb = get_report_cb; + callbacks.set_report_cb = set_report_cb; + callbacks.set_protocol_cb = set_protocol_cb; + callbacks.intr_data_cb = intr_data_cb; + callbacks.vc_unplug_cb = vc_unplug_cb; + + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK( ret ); + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + esp_bt_mem_release(ESP_BT_MODE_BLE); + if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) { + ESP_LOGE(TAG, "initialize controller failed: %s\n", esp_err_to_name(ret)); + return; + } + + if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) { + ESP_LOGE(TAG, "enable controller failed: %s\n", esp_err_to_name(ret)); + return; + } + + if ((ret = esp_bluedroid_init()) != ESP_OK) { + ESP_LOGE(TAG, "initialize bluedroid failed: %s\n", esp_err_to_name(ret)); + return; + } + + if ((ret = esp_bluedroid_enable()) != ESP_OK) { + ESP_LOGE(TAG, "enable bluedroid failed: %s\n", esp_err_to_name(ret)); + return; + } + esp_bt_gap_register_callback(esp_bt_gap_cb); + ESP_LOGI(TAG, "setting hid parameters"); + esp_hid_device_register_app(&app_param, &both_qos, &both_qos); + + ESP_LOGI(TAG, "starting hid device"); + esp_hid_device_init(&callbacks); + + ESP_LOGI(TAG, "setting device name"); + esp_bt_dev_set_device_name("Pro Controller"); + + ESP_LOGI(TAG, "setting to connectable, discoverable"); + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + //start blinking + xTaskCreate(startBlink, "blink_task", 1024, NULL, 1, &BlinkHandle); + + +} diff --git a/Firmware/BlueCubeModv2/sdkconfig b/Firmware/BlueCubeModv2/sdkconfig new file mode 100644 index 0000000..e54e38e --- /dev/null +++ b/Firmware/BlueCubeModv2/sdkconfig @@ -0,0 +1,705 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# +CONFIG_IDF_TARGET="esp32" + +# +# SDK tool configuration +# +CONFIG_SDK_TOOLPREFIX="xtensa-esp32-elf-" +CONFIG_SDK_PYTHON="python" +CONFIG_SDK_MAKE_WARN_UNDEFINED_VARIABLES=y +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT_ENABLED is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +CONFIG_ESPTOOLPY_PORT="/dev/cu.SLAB_USBtoUART" +# CONFIG_ESPTOOLPY_BAUD_115200B is not set +# CONFIG_ESPTOOLPY_BAUD_230400B is not set +CONFIG_ESPTOOLPY_BAUD_921600B=y +# CONFIG_ESPTOOLPY_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_BAUD=921600 +CONFIG_ESPTOOLPY_COMPRESSED=y +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +# CONFIG_MONITOR_BAUD_9600B is not set +# CONFIG_MONITOR_BAUD_57600B is not set +CONFIG_MONITOR_BAUD_115200B=y +# CONFIG_MONITOR_BAUD_230400B is not set +# CONFIG_MONITOR_BAUD_921600B is not set +# CONFIG_MONITOR_BAUD_2MB is not set +# CONFIG_MONITOR_BAUD_OTHER is not set +CONFIG_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_MONITOR_BAUD=115200 +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +CONFIG_OPTIMIZATION_LEVEL_DEBUG=y +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_STACK_CHECK is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_DISABLE_GCC8_WARNINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +# CONFIG_ESP32_APPTRACE_ENABLE is not set +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_BT_ENABLED=y +# CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY is not set +CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y +# CONFIG_BTDM_CONTROLLER_MODE_BTDM is not set +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN=4 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN=2 +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=4 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=2 +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_0=y +# CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_1 is not set +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 +CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y +# CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 is not set +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=y +CONFIG_BTDM_MODEM_SLEEP_MODE_ORIG=y +# CONFIG_BTDM_MODEM_SLEEP_MODE_EVED is not set +CONFIG_BTDM_LPCLK_SEL_MAIN_XTAL=y +CONFIG_BLUEDROID_ENABLED=y +CONFIG_BLUEDROID_PINNED_TO_CORE_0=y +# CONFIG_BLUEDROID_PINNED_TO_CORE_1 is not set +CONFIG_BLUEDROID_PINNED_TO_CORE=0 +CONFIG_BTC_TASK_STACK_SIZE=4096 +CONFIG_BTU_TASK_STACK_SIZE=4096 +# CONFIG_BLUEDROID_MEM_DEBUG is not set +CONFIG_CLASSIC_BT_ENABLED=y +# CONFIG_A2DP_ENABLE is not set +# CONFIG_BT_SPP_ENABLED is not set +# CONFIG_HFP_ENABLE is not set +CONFIG_BT_SSP_ENABLED=y +CONFIG_BT_HID_DEV_ENABLED=y +# CONFIG_BT_STACK_NO_LOG is not set +# CONFIG_HCI_TRACE_LEVEL_NONE is not set +# CONFIG_HCI_TRACE_LEVEL_ERROR is not set +CONFIG_HCI_TRACE_LEVEL_WARNING=y +# CONFIG_HCI_TRACE_LEVEL_API is not set +# CONFIG_HCI_TRACE_LEVEL_EVENT is not set +# CONFIG_HCI_TRACE_LEVEL_DEBUG is not set +# CONFIG_HCI_TRACE_LEVEL_VERBOSE is not set +CONFIG_HCI_INITIAL_TRACE_LEVEL=2 +# CONFIG_BTM_TRACE_LEVEL_NONE is not set +# CONFIG_BTM_TRACE_LEVEL_ERROR is not set +CONFIG_BTM_TRACE_LEVEL_WARNING=y +# CONFIG_BTM_TRACE_LEVEL_API is not set +# CONFIG_BTM_TRACE_LEVEL_EVENT is not set +# CONFIG_BTM_TRACE_LEVEL_DEBUG is not set +# CONFIG_BTM_TRACE_LEVEL_VERBOSE is not set +CONFIG_BTM_INITIAL_TRACE_LEVEL=2 +# CONFIG_L2CAP_TRACE_LEVEL_NONE is not set +# CONFIG_L2CAP_TRACE_LEVEL_ERROR is not set +CONFIG_L2CAP_TRACE_LEVEL_WARNING=y +# CONFIG_L2CAP_TRACE_LEVEL_API is not set +# CONFIG_L2CAP_TRACE_LEVEL_EVENT is not set +# CONFIG_L2CAP_TRACE_LEVEL_DEBUG is not set +# CONFIG_L2CAP_TRACE_LEVEL_VERBOSE is not set +CONFIG_L2CAP_INITIAL_TRACE_LEVEL=2 +# CONFIG_RFCOMM_TRACE_LEVEL_NONE is not set +# CONFIG_RFCOMM_TRACE_LEVEL_ERROR is not set +CONFIG_RFCOMM_TRACE_LEVEL_WARNING=y +# CONFIG_RFCOMM_TRACE_LEVEL_API is not set +# CONFIG_RFCOMM_TRACE_LEVEL_EVENT is not set +# CONFIG_RFCOMM_TRACE_LEVEL_DEBUG is not set +# CONFIG_RFCOMM_TRACE_LEVEL_VERBOSE is not set +CONFIG_RFCOMM_INITIAL_TRACE_LEVEL=2 +# CONFIG_SDP_TRACE_LEVEL_NONE is not set +# CONFIG_SDP_TRACE_LEVEL_ERROR is not set +CONFIG_SDP_TRACE_LEVEL_WARNING=y +# CONFIG_SDP_TRACE_LEVEL_API is not set +# CONFIG_SDP_TRACE_LEVEL_EVENT is not set +# CONFIG_SDP_TRACE_LEVEL_DEBUG is not set +# CONFIG_SDP_TRACE_LEVEL_VERBOSE is not set +CONFIG_SDP_INITIAL_TRACE_LEVEL=2 +# CONFIG_GAP_TRACE_LEVEL_NONE is not set +# CONFIG_GAP_TRACE_LEVEL_ERROR is not set +CONFIG_GAP_TRACE_LEVEL_WARNING=y +# CONFIG_GAP_TRACE_LEVEL_API is not set +# CONFIG_GAP_TRACE_LEVEL_EVENT is not set +# CONFIG_GAP_TRACE_LEVEL_DEBUG is not set +# CONFIG_GAP_TRACE_LEVEL_VERBOSE is not set +CONFIG_GAP_INITIAL_TRACE_LEVEL=2 +# CONFIG_BNEP_TRACE_LEVEL_NONE is not set +# CONFIG_BNEP_TRACE_LEVEL_ERROR is not set +CONFIG_BNEP_TRACE_LEVEL_WARNING=y +# CONFIG_BNEP_TRACE_LEVEL_API is not set +# CONFIG_BNEP_TRACE_LEVEL_EVENT is not set +# CONFIG_BNEP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BNEP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BNEP_INITIAL_TRACE_LEVEL=2 +# CONFIG_PAN_TRACE_LEVEL_NONE is not set +# CONFIG_PAN_TRACE_LEVEL_ERROR is not set +CONFIG_PAN_TRACE_LEVEL_WARNING=y +# CONFIG_PAN_TRACE_LEVEL_API is not set +# CONFIG_PAN_TRACE_LEVEL_EVENT is not set +# CONFIG_PAN_TRACE_LEVEL_DEBUG is not set +# CONFIG_PAN_TRACE_LEVEL_VERBOSE is not set +CONFIG_PAN_INITIAL_TRACE_LEVEL=2 +# CONFIG_A2D_TRACE_LEVEL_NONE is not set +# CONFIG_A2D_TRACE_LEVEL_ERROR is not set +CONFIG_A2D_TRACE_LEVEL_WARNING=y +# CONFIG_A2D_TRACE_LEVEL_API is not set +# CONFIG_A2D_TRACE_LEVEL_EVENT is not set +# CONFIG_A2D_TRACE_LEVEL_DEBUG is not set +# CONFIG_A2D_TRACE_LEVEL_VERBOSE is not set +CONFIG_A2D_INITIAL_TRACE_LEVEL=2 +# CONFIG_AVDT_TRACE_LEVEL_NONE is not set +# CONFIG_AVDT_TRACE_LEVEL_ERROR is not set +CONFIG_AVDT_TRACE_LEVEL_WARNING=y +# CONFIG_AVDT_TRACE_LEVEL_API is not set +# CONFIG_AVDT_TRACE_LEVEL_EVENT is not set +# CONFIG_AVDT_TRACE_LEVEL_DEBUG is not set +# CONFIG_AVDT_TRACE_LEVEL_VERBOSE is not set +CONFIG_AVDT_INITIAL_TRACE_LEVEL=2 +# CONFIG_AVCT_TRACE_LEVEL_NONE is not set +# CONFIG_AVCT_TRACE_LEVEL_ERROR is not set +CONFIG_AVCT_TRACE_LEVEL_WARNING=y +# CONFIG_AVCT_TRACE_LEVEL_API is not set +# CONFIG_AVCT_TRACE_LEVEL_EVENT is not set +# CONFIG_AVCT_TRACE_LEVEL_DEBUG is not set +# CONFIG_AVCT_TRACE_LEVEL_VERBOSE is not set +CONFIG_AVCT_INITIAL_TRACE_LEVEL=2 +# CONFIG_AVRC_TRACE_LEVEL_NONE is not set +# CONFIG_AVRC_TRACE_LEVEL_ERROR is not set +CONFIG_AVRC_TRACE_LEVEL_WARNING=y +# CONFIG_AVRC_TRACE_LEVEL_API is not set +# CONFIG_AVRC_TRACE_LEVEL_EVENT is not set +# CONFIG_AVRC_TRACE_LEVEL_DEBUG is not set +# CONFIG_AVRC_TRACE_LEVEL_VERBOSE is not set +CONFIG_AVRC_INITIAL_TRACE_LEVEL=2 +# CONFIG_MCA_TRACE_LEVEL_NONE is not set +# CONFIG_MCA_TRACE_LEVEL_ERROR is not set +CONFIG_MCA_TRACE_LEVEL_WARNING=y +# CONFIG_MCA_TRACE_LEVEL_API is not set +# CONFIG_MCA_TRACE_LEVEL_EVENT is not set +# CONFIG_MCA_TRACE_LEVEL_DEBUG is not set +# CONFIG_MCA_TRACE_LEVEL_VERBOSE is not set +CONFIG_MCA_INITIAL_TRACE_LEVEL=2 +# CONFIG_HID_TRACE_LEVEL_NONE is not set +# CONFIG_HID_TRACE_LEVEL_ERROR is not set +CONFIG_HID_TRACE_LEVEL_WARNING=y +# CONFIG_HID_TRACE_LEVEL_API is not set +# CONFIG_HID_TRACE_LEVEL_EVENT is not set +# CONFIG_HID_TRACE_LEVEL_DEBUG is not set +# CONFIG_HID_TRACE_LEVEL_VERBOSE is not set +CONFIG_HID_INITIAL_TRACE_LEVEL=2 +# CONFIG_HIDD_TRACE_LEVEL_NONE is not set +# CONFIG_HIDD_TRACE_LEVEL_ERROR is not set +CONFIG_HIDD_TRACE_LEVEL_WARNING=y +# CONFIG_HIDD_TRACE_LEVEL_API is not set +# CONFIG_HIDD_TRACE_LEVEL_EVENT is not set +# CONFIG_HIDD_TRACE_LEVEL_DEBUG is not set +# CONFIG_HIDD_TRACE_LEVEL_VERBOSE is not set +CONFIG_HIDD_INITIAL_TRACE_LEVEL=2 +# CONFIG_APPL_TRACE_LEVEL_NONE is not set +# CONFIG_APPL_TRACE_LEVEL_ERROR is not set +CONFIG_APPL_TRACE_LEVEL_WARNING=y +# CONFIG_APPL_TRACE_LEVEL_API is not set +# CONFIG_APPL_TRACE_LEVEL_EVENT is not set +# CONFIG_APPL_TRACE_LEVEL_DEBUG is not set +# CONFIG_APPL_TRACE_LEVEL_VERBOSE is not set +CONFIG_APPL_INITIAL_TRACE_LEVEL=2 +# CONFIG_GATT_TRACE_LEVEL_NONE is not set +# CONFIG_GATT_TRACE_LEVEL_ERROR is not set +CONFIG_GATT_TRACE_LEVEL_WARNING=y +# CONFIG_GATT_TRACE_LEVEL_API is not set +# CONFIG_GATT_TRACE_LEVEL_EVENT is not set +# CONFIG_GATT_TRACE_LEVEL_DEBUG is not set +# CONFIG_GATT_TRACE_LEVEL_VERBOSE is not set +CONFIG_GATT_INITIAL_TRACE_LEVEL=2 +# CONFIG_SMP_TRACE_LEVEL_NONE is not set +# CONFIG_SMP_TRACE_LEVEL_ERROR is not set +CONFIG_SMP_TRACE_LEVEL_WARNING=y +# CONFIG_SMP_TRACE_LEVEL_API is not set +# CONFIG_SMP_TRACE_LEVEL_EVENT is not set +# CONFIG_SMP_TRACE_LEVEL_DEBUG is not set +# CONFIG_SMP_TRACE_LEVEL_VERBOSE is not set +CONFIG_SMP_INITIAL_TRACE_LEVEL=2 +# CONFIG_BTIF_TRACE_LEVEL_NONE is not set +# CONFIG_BTIF_TRACE_LEVEL_ERROR is not set +CONFIG_BTIF_TRACE_LEVEL_WARNING=y +# CONFIG_BTIF_TRACE_LEVEL_API is not set +# CONFIG_BTIF_TRACE_LEVEL_EVENT is not set +# CONFIG_BTIF_TRACE_LEVEL_DEBUG is not set +# CONFIG_BTIF_TRACE_LEVEL_VERBOSE is not set +CONFIG_BTIF_INITIAL_TRACE_LEVEL=2 +# CONFIG_BTC_TRACE_LEVEL_NONE is not set +# CONFIG_BTC_TRACE_LEVEL_ERROR is not set +CONFIG_BTC_TRACE_LEVEL_WARNING=y +# CONFIG_BTC_TRACE_LEVEL_API is not set +# CONFIG_BTC_TRACE_LEVEL_EVENT is not set +# CONFIG_BTC_TRACE_LEVEL_DEBUG is not set +# CONFIG_BTC_TRACE_LEVEL_VERBOSE is not set +CONFIG_BTC_INITIAL_TRACE_LEVEL=2 +# CONFIG_OSI_TRACE_LEVEL_NONE is not set +# CONFIG_OSI_TRACE_LEVEL_ERROR is not set +CONFIG_OSI_TRACE_LEVEL_WARNING=y +# CONFIG_OSI_TRACE_LEVEL_API is not set +# CONFIG_OSI_TRACE_LEVEL_EVENT is not set +# CONFIG_OSI_TRACE_LEVEL_DEBUG is not set +# CONFIG_OSI_TRACE_LEVEL_VERBOSE is not set +CONFIG_OSI_INITIAL_TRACE_LEVEL=2 +# CONFIG_BLUFI_TRACE_LEVEL_NONE is not set +# CONFIG_BLUFI_TRACE_LEVEL_ERROR is not set +CONFIG_BLUFI_TRACE_LEVEL_WARNING=y +# CONFIG_BLUFI_TRACE_LEVEL_API is not set +# CONFIG_BLUFI_TRACE_LEVEL_EVENT is not set +# CONFIG_BLUFI_TRACE_LEVEL_DEBUG is not set +# CONFIG_BLUFI_TRACE_LEVEL_VERBOSE is not set +CONFIG_BLUFI_INITIAL_TRACE_LEVEL=2 +CONFIG_BT_ACL_CONNECTIONS=4 +# CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST is not set +# CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY is not set +# CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK is not set +CONFIG_SMP_ENABLE=y +CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT=30 +CONFIG_BT_RESERVE_DRAM=0xdb5c +# CONFIG_ADC_FORCE_XPD_FSM is not set +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set +CONFIG_EFUSE_MAX_BLK_LEN=192 +CONFIG_IDF_TARGET_ESP32=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 +# CONFIG_SPIRAM_SUPPORT is not set +# CONFIG_MEMMAP_TRACEMEM is not set +# CONFIG_MEMMAP_TRACEMEM_TWOBANKS is not set +# CONFIG_ESP32_TRAX is not set +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set +CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y +CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=4096 +CONFIG_MAIN_TASK_STACK_SIZE=4096 +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +# CONFIG_ULP_COPROC_ENABLED is not set +CONFIG_ULP_COPROC_RESERVE_MEM=0 +# CONFIG_ESP32_PANIC_PRINT_HALT is not set +CONFIG_ESP32_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32_PANIC_GDBSTUB is not set +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_ESP32_DEBUG_STUBS_ENABLE=y +# CONFIG_INT_WDT is not set +# CONFIG_TASK_WDT is not set +CONFIG_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_BROWNOUT_DET_LVL=0 +CONFIG_REDUCE_PHY_TX_POWER=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32_XTAL_FREQ_40=y +# CONFIG_ESP32_XTAL_FREQ_26 is not set +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=40 +# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set +# CONFIG_ESP_TIMER_PROFILING is not set +# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# CONFIG_PM_ENABLE is not set +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +# CONFIG_OTA_ALLOW_HTTP is not set +CONFIG_SW_COEXIST_ENABLE=y +# CONFIG_SW_COEXIST_PREFERENCE_WIFI is not set +# CONFIG_SW_COEXIST_PREFERENCE_BT is not set +CONFIG_SW_COEXIST_PREFERENCE_BALANCE=y +CONFIG_SW_COEXIST_PREFERENCE_VALUE=2 +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE is not set +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +# CONFIG_ESP32_ENABLE_COREDUMP is not set +CONFIG_DMA_RX_BUF_NUM=10 +CONFIG_DMA_TX_BUF_NUM=10 +CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE=y +CONFIG_EMAC_CHECK_LINK_PERIOD_MS=2000 +CONFIG_EMAC_TASK_PRIORITY=20 +CONFIG_EMAC_TASK_STACK_SIZE=3072 +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_MB_QUEUE_LENGTH=20 +CONFIG_MB_SERIAL_TASK_STACK_SIZE=2048 +CONFIG_MB_SERIAL_BUF_SIZE=256 +CONFIG_MB_SERIAL_TASK_PRIO=10 +# CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT is not set +CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_MB_CONTROLLER_STACK_SIZE=4096 +CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 +CONFIG_MB_TIMER_PORT_ENABLED=y +CONFIG_MB_TIMER_GROUP=0 +CONFIG_MB_TIMER_INDEX=0 +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y +# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set +# CONFIG_FREERTOS_ASSERT_DISABLE is not set +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +# CONFIG_FREERTOS_LEGACY_HOOKS is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_SUPPORT_STATIC_ALLOCATION is not set +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_DEBUG_INTERNALS is not set +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_TRACING is not set +CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_COLORS=y +# CONFIG_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_USE_ONLY_LWIP_SELECT is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# CONFIG_LWIP_SO_RCVBUF is not set +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 +# CONFIG_LWIP_IP_FRAG is not set +# CONFIG_LWIP_IP_REASSEMBLY is not set +# CONFIG_LWIP_STATS is not set +# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=6 +CONFIG_TCP_MSS=1436 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5744 +CONFIG_TCP_WND_DEFAULT=5744 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +# CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +CONFIG_LWIP_MAX_RAW_PCBS=16 +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 +# CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN is not set +# CONFIG_MBEDTLS_DEBUG is not set +CONFIG_MBEDTLS_HARDWARE_AES=y +# CONFIG_MBEDTLS_HARDWARE_MPI is not set +# CONFIG_MBEDTLS_HARDWARE_SHA is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set +CONFIG_MBEDTLS_SSL_PROTO_TLS1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +CONFIG_MBEDTLS_RC4_DISABLED=y +# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set +# CONFIG_MBEDTLS_RC4_ENABLED is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_RIPEMD160_C is not set +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MQTT_PROTOCOL_311=y +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# CONFIG_OPENSSL_DEBUG is not set +CONFIG_OPENSSL_ASSERT_DO_NOTHING=y +# CONFIG_OPENSSL_ASSERT_EXIT is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPIFFS_MAX_PARTITIONS=3 +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +CONFIG_IP_LOST_TIMER_INTERVAL=120 +CONFIG_TCPIP_LWIP=y +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set + +# Deprecated options for backward compatibility +CONFIG_TOOLPREFIX="xtensa-esp32-elf-" +CONFIG_PYTHON="python" +CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y +# End of deprecated options diff --git a/PCB/BlueCubeModRev2Schematics.pdf b/PCB/BlueCubeModRev2Schematics.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a2d5069916b6cfdbd00057f25e55e91a1f100175 GIT binary patch literal 32759 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 literal 0 HcmV?d00001 diff --git a/PCB/Eagle/BlueCubeModR2.brd b/PCB/Eagle/BlueCubeModR2.brd index df73aaf..ed18c0d 100644 --- a/PCB/Eagle/BlueCubeModR2.brd +++ b/PCB/Eagle/BlueCubeModR2.brd @@ -627,13 +627,11 @@ Example Datasheet - - @@ -641,6 +639,10 @@ Example Datasheet + + +ON + @@ -1098,12 +1100,12 @@ Note, that not all DRC settings must be set by the manufacturer. Several can be - - + + - + @@ -1111,16 +1113,16 @@ Note, that not all DRC settings must be set by the manufacturer. Several can be - - + + - - + + @@ -1156,7 +1158,7 @@ Note, that not all DRC settings must be set by the manufacturer. Several can be - + @@ -1165,8 +1167,9 @@ Note, that not all DRC settings must be set by the manufacturer. Several can be - - + + + @@ -1216,20 +1219,11 @@ Note, that not all DRC settings must be set by the manufacturer. Several can be - - - - - - - - - @@ -1241,14 +1235,6 @@ Note, that not all DRC settings must be set by the manufacturer. Several can be - - - - - - - - @@ -1582,8 +1568,10 @@ Note, that not all DRC settings must be set by the manufacturer. Several can be - - + + + + @@ -1655,6 +1643,19 @@ Note, that not all DRC settings must be set by the manufacturer. Several can be + + + + + + + + + + + + + diff --git a/PCB/Eagle/BlueCubeModR2.sch b/PCB/Eagle/BlueCubeModR2.sch index 99dd89e..998ee9d 100644 --- a/PCB/Eagle/BlueCubeModR2.sch +++ b/PCB/Eagle/BlueCubeModR2.sch @@ -1816,13 +1816,11 @@ Datasheet - - @@ -1830,6 +1828,10 @@ Datasheet + + +ON + @@ -2450,11 +2452,12 @@ Datasheet -