Englebert
1 year ago
commit
395dedf08e
10 changed files with 1738 additions and 0 deletions
-
83README.md
-
39include/README
-
46lib/README
-
15platformio.ini
-
BINsrc/.main.cpp.swp
-
BINsrc/.main.h.swp
-
225src/i2c_protocols.h
-
1063src/main.cpp
-
256src/main.h
-
11test/README
@ -0,0 +1,83 @@ |
|||
|
|||
|
|||
+-----------------------+ |
|||
| O | USB | O | |
|||
| ------- | |
|||
[ OLED VCC ] 3V3 | [ ] [ ] | VIN [ 5V FROM RPi ] |
|||
[ Ground From Pi ] GND | [ ] [ ] | GND [ GROUND FROM RPi ] |
|||
[ ] Touch3 / HSPI_CS0 / ADC2_3 / GPIO15 | [ ] [ ] | GPIO13 / ADC2_4 / HSPI_ID / Touch4 [ BUTTON8 ] |
|||
[ ] CS / Touch2 / HSPI_WP / ADC2_2 / GPIO2 | [ ] [ ] | GPIO12 / ADC2_5 / HSPI_Q / Touch5 [ BUTTON7 ] |
|||
[ BUTTON9 ] Touch0 / HSPI_HD / ADC2_0 / GPIO4 | [ ] [ ] | GPIO14 / ADC2_6 / HSPI_CLK / Touch6 [ BUTTON6 ] |
|||
[ I2C2_SDA ] U2_RXD / GPIO16 | [ ] [ ] | GPIO27 / ADC2_7 / Touch7 [ BUTTON5 ] |
|||
[ I2C2_SCL ] U2_TXD / GPIO17 | [ ] [ ] | GPIO26 / ADC2_9 / DAC2 [ BUTTON4 ] |
|||
[ BUTTON10 ] V_SPI_CS0 / GPIO5 | [ ] ___________ [ ] | GPIO25 / ADC2_8 / DAC1 [ BUTTON3 ] |
|||
[ BUTTON1 ] SCK / V_SPI_CLK / GPIO18 | [ ] | | [ ] | GPIO33 / ADC1_5 / Touch8 / XTAL32 [ A_SENSE ] |
|||
[ BUTTON2 ] U0_CTS / MSIO / V_SPI_Q / GPIO19 | [ ] | | [ ] | GPIO32 / ADC1_4 / Touch9 / XTAL32 [ V_SENSE ] |
|||
[ SDA to Pi ] SDA / V_SPI_HD / GPIO21 | [ ] | | [ ] | GPIO35 / ADC1_7 [ ROLL ] |
|||
[ ] CLK2 / U0_RXD / GPIO3 | [ ] | | [ ] | GPIO34 / ADC1_6 [ PITCH ] |
|||
[ ] CLK3 / U0_TXD / GPIO1 | [ ] | | [ ] | GPIO39 / ADC1_3 / SensVN [ YAW ] |
|||
[ SCL to Pi ] SCL / U0_RTS / V_SPI_WP / GPIO22 | [ ] | | [ ] | GPIO36 / ADC1_0 / SensVP [ THROTTLE ] |
|||
[ ] MOSI / V_SPI_WP / GPIO23 | [ ] |___________| [ ] | EN |
|||
| | |
|||
| | | ____ ____ | | |
|||
| | | | | | | | | |
|||
| |__|__| |__| |__| | |
|||
| O O | |
|||
+-----------------------+ |
|||
|
|||
Power Pins |
|||
---------- |
|||
|
|||
VIN - VIN pin can be used to directly supply the ESP32 and its peripherals, if you have a regulated 5V voltage source. |
|||
3V3 - 3.3V pin is the output of an on-board voltage regulator. This pin can be used to supply power to external components. |
|||
GND - Ground pin(s) |
|||
|
|||
GPIO Pins |
|||
--------- |
|||
ESP32 development board has 25 GPIO pins which can be assigned to various functions programmatically. |
|||
Each digital enabled GPIO can be configured to internal pull-up or pull-down, or set to high impedance. |
|||
When configured as an input, it can also be set to edge-trigger or level-trigger to generate CPU interrupts. |
|||
|
|||
ADC Channels |
|||
------------ |
|||
The board integrates 12-bit SAR ADCs and supports measurements on 15 channels (analog enabled pins). |
|||
Some of these pins can be used to build a programmable gain amplifier which is used for the measurement of |
|||
small analog signals. The ESP32 is also designed to measure the voltages while operating in the sleep mode. |
|||
|
|||
DAC Channels |
|||
------------ |
|||
he board features two 8-bit DAC channels to convert digital signals into true analog voltages. This dual DAC |
|||
can drive other circuits. |
|||
|
|||
Touch Pads |
|||
---------- |
|||
The board offers 9 capacitive sensing GPIOs which detect capacitive variations introduced by the GPIO’s direct |
|||
contact or close proximity with a finger or other objects. |
|||
|
|||
UART Pins |
|||
--------- |
|||
ESP32 development board has 2 UART interfaces, i.e. UART0 and UART2, which provide asynchronous communication |
|||
(RS232 and RS485) and IrDA support, and communicate at up to 5 Mbps. UART provides hardware management of the |
|||
CTS and RTS signals and software flow control (XON and XOFF) as well. |
|||
|
|||
SPI Pins |
|||
-------- |
|||
SPI Pins ESP32 features three SPIs (SPI, HSPI and VSPI) in slave and master modes. These SPIs also support the |
|||
following general-purpose SPI features: |
|||
|
|||
- 4 timing modes of the SPI format transfer |
|||
- Up to 80 MHz and the divided clocks of 80 MHz |
|||
- Up to 64-Byte FIFO |
|||
- All SPIs can also be used to connect to the external Flash/SRAM and LCD. |
|||
|
|||
PWM Pins |
|||
-------- |
|||
The board has 25 channels (Nearly All GPIO pins) of PWM pins controlled by Pulse Width Modulation (PWM) controller. |
|||
The PWM output can be used for driving digital motors and LEDs. The controller consists of PWM timers and the PWM |
|||
operator. Each timer provides timing in synchronous or independent form, and each PWM operator generates the waveform |
|||
for one PWM channel. |
|||
|
|||
|
|||
EN Pin |
|||
------ |
|||
Used to enable ESP32. The chip is enabled when pulled HIGH. When pulled LOW the chip works at minimum power. |
@ -0,0 +1,39 @@ |
|||
|
|||
This directory is intended for project header files. |
|||
|
|||
A header file is a file containing C declarations and macro definitions |
|||
to be shared between several project source files. You request the use of a |
|||
header file in your project source file (C, C++, etc) located in `src` folder |
|||
by including it, with the C preprocessing directive `#include'. |
|||
|
|||
```src/main.c |
|||
|
|||
#include "header.h" |
|||
|
|||
int main (void) |
|||
{ |
|||
... |
|||
} |
|||
``` |
|||
|
|||
Including a header file produces the same results as copying the header file |
|||
into each source file that needs it. Such copying would be time-consuming |
|||
and error-prone. With a header file, the related declarations appear |
|||
in only one place. If they need to be changed, they can be changed in one |
|||
place, and programs that include the header file will automatically use the |
|||
new version when next recompiled. The header file eliminates the labor of |
|||
finding and changing all the copies as well as the risk that a failure to |
|||
find one copy will result in inconsistencies within a program. |
|||
|
|||
In C, the usual convention is to give header files names that end with `.h'. |
|||
It is most portable to use only letters, digits, dashes, and underscores in |
|||
header file names, and at most one dot. |
|||
|
|||
Read more about using header files in official GCC documentation: |
|||
|
|||
* Include Syntax |
|||
* Include Operation |
|||
* Once-Only Headers |
|||
* Computed Includes |
|||
|
|||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html |
@ -0,0 +1,46 @@ |
|||
|
|||
This directory is intended for project specific (private) libraries. |
|||
PlatformIO will compile them to static libraries and link into executable file. |
|||
|
|||
The source code of each library should be placed in a an own separate directory |
|||
("lib/your_library_name/[here are source files]"). |
|||
|
|||
For example, see a structure of the following two libraries `Foo` and `Bar`: |
|||
|
|||
|--lib |
|||
| | |
|||
| |--Bar |
|||
| | |--docs |
|||
| | |--examples |
|||
| | |--src |
|||
| | |- Bar.c |
|||
| | |- Bar.h |
|||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html |
|||
| | |
|||
| |--Foo |
|||
| | |- Foo.c |
|||
| | |- Foo.h |
|||
| | |
|||
| |- README --> THIS FILE |
|||
| |
|||
|- platformio.ini |
|||
|--src |
|||
|- main.c |
|||
|
|||
and a contents of `src/main.c`: |
|||
``` |
|||
#include <Foo.h> |
|||
#include <Bar.h> |
|||
|
|||
int main (void) |
|||
{ |
|||
... |
|||
} |
|||
|
|||
``` |
|||
|
|||
PlatformIO Library Dependency Finder will find automatically dependent |
|||
libraries scanning project source files. |
|||
|
|||
More information about PlatformIO Library Dependency Finder |
|||
- https://docs.platformio.org/page/librarymanager/ldf.html |
@ -0,0 +1,15 @@ |
|||
; PlatformIO Project Configuration File |
|||
; |
|||
; Build options: build flags, source filter |
|||
; Upload options: custom upload port, speed and extra flags |
|||
; Library options: dependencies, extra library storages |
|||
; Advanced options: extra scripting |
|||
; |
|||
; Please visit documentation for the other options and examples |
|||
; https://docs.platformio.org/page/projectconf.html |
|||
|
|||
[env:esp32dev] |
|||
platform = espressif32 |
|||
board = esp32dev |
|||
framework = arduino |
|||
lib_deps = thingpulse/ESP8266 and ESP32 OLED driver for SSD1306 displays@^4.4.0 |
@ -0,0 +1,225 @@ |
|||
#pragma once |
|||
|
|||
#include <stdint.h> |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
typedef unsigned int u32; |
|||
typedef unsigned short u16; |
|||
typedef unsigned char u8; |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
// Protocol is: |
|||
// 1. * Master sends a command to slave (2...N bytes, depending on command type). First byte of all commands is the command start flag; |
|||
// 2. * Slave responds with the right answer based on the command (1...N bytes, depending on command response type); |
|||
// 3. * Repeat the steps above; |
|||
// That means: slave device (Ruby extension device) just waits on I2C for commands from master (Ruby main controller) and responds to those commands as needed. |
|||
// Note!!! All commands and responses have 1 extra byte at the end as the CRC |
|||
// Use the example function at the end of file to compute the CRC |
|||
// Note!!! Always check the CRC value when you get something. Ignore the commands with bad CRC. There can always be noise or bad I2C devices on the I2C bus. |
|||
|
|||
|
|||
#define I2C_DEVICE_DEFAULT_ADDRESS 0x60 |
|||
#define I2C_DEVICE_MIN_ADDRESS_RANGE 0x60 |
|||
#define I2C_DEVICE_MAX_ADDRESS_RANGE 0x6F |
|||
|
|||
// Note: the address [I2C_DEVICE_MAX_ADDRESS_RANGE-2] is used by the Ruby Pico Extender. If you use one, your plugin should use a different address. |
|||
|
|||
#define I2C_PROTOCOL_STRING_LENGTH 24 |
|||
|
|||
// Capabilities flags supported by the slave Ruby device; these capabilities will be queried by the Ruby controller and will be reported back to Ruby controller using the I2C interface; |
|||
|
|||
#define I2C_CAPABILITY_FLAG_SPI ((u16)(((u16)0x01)<<1)) // Set if the slave device does support SPI communication with the Ruby controller (if not, only I2C is used) |
|||
#define I2C_CAPABILITY_FLAG_BUTTONS ((u16)(((u16)0x01)<<2)) // Set if the slave device has buttons (for UI navigation in Ruby); |
|||
#define I2C_CAPABILITY_FLAG_ROTARY ((u16)(((u16)0x01)<<3)) // Set if the slave device has rotary encoder (for UI navigation/Camera control); |
|||
#define I2C_CAPABILITY_FLAG_ROTARY2 ((u16)(((u16)0x01)<<4)) // Set if the slave device has the secondary rotary encoder (for UI navigation/Camera control); |
|||
#define I2C_CAPABILITY_FLAG_LEDS ((u16)(((u16)0x01)<<5)) // Set if the slave device has LEDs to be controlled by the Ruby controller; |
|||
#define I2C_CAPABILITY_FLAG_RC_INPUT ((u16)(((u16)0x01)<<6)) // Set if the slave device has RC input hardware; |
|||
#define I2C_CAPABILITY_FLAG_RC_OUTPUT ((u16)(((u16)0x01)<<7)) // Set if the slave device should output RC frames to the FC; |
|||
#define I2C_CAPABILITY_FLAG_FLIGHT_CONTROL ((u16)(((u16)0x01)<<8)) // Set if the slave device wants to send flight commands to the vehicle; |
|||
#define I2C_CAPABILITY_FLAG_CAMERA_CONTROL ((u16)(((u16)0x01)<<9)) // Set if the slave device wants to send camera commands (brightness, contrast, etc); |
|||
#define I2C_CAPABILITY_FLAG_SOUNDS ((u16)(((u16)0x01)<<10)) // Set if the slave device can play sounds (alarms); |
|||
|
|||
#define I2C_COMMAND_START_FLAG 0xFF |
|||
|
|||
#define I2C_COMMAND_ID_GET_FLAGS 0x01 |
|||
// Get flags: master asks the slave for the capabilities it supports; |
|||
// Master sends: 1 byte: command id (I2C_COMMAND_ID_GET_FLAGS) |
|||
// Slave responds: 2 bytes: capabilities (flags as OR-ed bits) supported by the I2C device; |
|||
|
|||
|
|||
#define I2C_COMMAND_ID_GET_VERSION 0x02 |
|||
// Get flags: master asks the slave for the version; |
|||
// Master sends: 1 byte: command id (I2C_COMMAND_ID_GET_VERSION); |
|||
// Slave responds: 1 byte: version of the software on the I2C slave device; |
|||
|
|||
|
|||
#define I2C_COMMAND_ID_GET_NAME 0x03 |
|||
// Get name: master asks slave for the device name, to be used in the user interface; |
|||
// Master sends: 1 byte: command id; |
|||
// Slave responds: I2C_PROTOCOL_STRING_LENGTH bytes: null terminated string, padded with 0 up to I2C_PROTOCOL_STRING_LENGTH bytes; |
|||
|
|||
|
|||
#define I2C_COMMAND_ID_SET_ADDRESS 0x04 |
|||
// Set address: master asks slave to set it's address to a custom one, to avoid conflicts |
|||
// Master sends: 2 bytes: command id and the new I2C address to be used by slave device; |
|||
// Slave responds: 1 byte: 0 - ok, 1 - error |
|||
|
|||
|
|||
#define I2C_COMMAND_ID_GET_BUTTONS_EVENTS 0x10 |
|||
// Get buttons: master asks slave if any buttons where pressed; |
|||
// Master sends: 1 byte: command id; |
|||
// Slave responds: 4 bytes: |
|||
// first 2 bytes: each bit represents 1 if a button was pressed, for a possible of 16 buttons on the device; |
|||
// last 2 bytes: each bit represents 1 if a button was long pressed, for a possible of 16 buttons on the device; |
|||
// bit 0 - Menu/Ok button |
|||
// bit 1 - Cancel button |
|||
// bit 2 - Plus button |
|||
// bit 3 - Minus button |
|||
// bit 4 - QA1 button |
|||
// bit 5 - QA2 button |
|||
// bit 6 - QA3 button |
|||
// bit 7 - Action Plus button |
|||
// bit 8 - Action Minus button |
|||
// bit 9... - future use |
|||
|
|||
|
|||
|
|||
#define I2C_COMMAND_ID_GET_ROTARY_EVENTS 0x11 |
|||
#define I2C_COMMAND_ID_GET_ROTARY_EVENTS2 0x12 |
|||
// Get rotary encoder events (for main and secondary rotary encoders, if present); |
|||
// Master asks slave if any rotary encoder events (first or secondary rotary encoder) took place. |
|||
// Master sends: 1 byte: command id; |
|||
// Slave responds: 1 byte: each bit represents: |
|||
// bit 0: rotary encoder was pressed; |
|||
// bit 1: rotary encoder was long pressed; |
|||
// bit 2: rotary encoder was rotated CCW; |
|||
// bit 3: rotary encoder was rotated CW; |
|||
// bit 4: rotary encoder was rotated fast CCW; |
|||
// bit 5: rotary encoder was rotated fast CW; |
|||
|
|||
|
|||
#define I2C_COMMAND_ID_SET_RC_INPUT_FLAGS 0x20 |
|||
#define I2C_COMMAND_RC_FLAG_SBUS 1 |
|||
#define I2C_COMMAND_RC_FLAG_IBUS (1<<1) |
|||
#define I2C_COMMAND_RC_FLAG_PPM (1<<2) |
|||
#define I2C_COMMAND_RC_FLAG_INVERT_UART (1<<4) |
|||
// Set RC Input flags: master tells the slave what RC protocol to read and if the RC input UART should be inverted or not (SBUS should be inverted). |
|||
// Master sends: 2 bytes: command id and the RC input flags: |
|||
// bit 0-4: RC protocol: 1 - parse SBUS RC input; 2 - parse IBUS RC input; 4 - parse PPM RC input; |
|||
// bit 4: 0 - non inverted UART, 1 - invert UART; |
|||
// Slave responds: 1 byte: 0 - ok, 1 - error |
|||
|
|||
#define I2C_COMMAND_ID_RC_GET_CHANNELS 0x21 |
|||
// Gets the current RC channels values from the slave device; |
|||
// Master sends: 1 byte: command id; |
|||
// Slave responds: 26 bytes: 1 byte flags, 1 byte frame number, 24 bytes for RC channels values (16 channels, 12 bits per channel, for 0...4095 posible values). |
|||
// byte 0: flags: bit 0 is set if RC input failsafe event occured on the slave device. |
|||
// byte 1: frame number: monotonically increasing on each received RC frame |
|||
// byte 1-16 - LSBits (8 bits) of each channel, from ch 1 to ch 16; |
|||
// byte 17-24 - MSBits (4 bits) of each channel, from ch 1 to ch 16; |
|||
// Unused channels should be set to zero. |
|||
|
|||
|
|||
#define I2C_COMMAND_ID_SET_RC_OUTPUT_FLAGS 0x30 |
|||
// Set RC Output flags: master tells the slave what RC protocol to generate and if the RC output UART should be inverted or not (SBUS should be inverted). |
|||
// Master sends: 2 bytes: command id and the RC output flags (same bits as RC input flags): |
|||
// bit 0-4: RC protocol: 1 - SBUS RC output; 2 - IBUS RC output; 4 - PPM RC output; |
|||
// bit 4: 0 - non inverted UART, 1 - invert UART; |
|||
// Slave responds: 1 byte: 0 - ok, 1 - error |
|||
|
|||
|
|||
#define I2C_COMMAND_ID_RC_SET_CHANNELS 0x31 |
|||
// Sets the current RC channels values to the slave device; |
|||
// Master sends: 26 bytes: 1 byte command id, 1 byte flags, 24 bytes: RC channels values (16 channels, 12 bits per channel, for 0...4095 posible values). |
|||
// byte 0: command id (this one); |
|||
// byte 1: flags: bit 0: set if failsafe should be signaled by the slave device; not set otherways; |
|||
// byte 2-17 - LSBits (8 bits) of each channel, from ch 1 to ch 16; |
|||
// byte 18-25 - MSBits (4 bits) of each channel, from ch 1 to ch 16; |
|||
// Unused channels should be set to zero. |
|||
|
|||
|
|||
#define I2C_COMMAND_ID_FLIGHT_CTRL_QUERY_ARM 0x40 |
|||
// Ask the slave device if the vehicle should receive the arm or disarm command |
|||
// Master sends: 1 byte: command id; |
|||
// Slave responds: 1 byte: |
|||
// bit 0: 0 - no change; 1 - has new arm state |
|||
// bit 1: 0 - disarm; 1 - arm |
|||
|
|||
#define I2C_COMMAND_ID_FLIGHT_CTRL_QUERY_MODE 0x41 |
|||
// Ask the slave device if the vehicle should receive a new flight mode |
|||
// Master sends: 1 byte: command id; |
|||
// Slave responds: 1 byte: |
|||
// bit 0: 0 - no change; 1 - has new flight mode; |
|||
// bit 1..7: new flight mode as defined by ArduPilot; |
|||
|
|||
|
|||
#define I2C_COMMAND_ID_CAMERA_CTRL_QUERY 0x50 |
|||
// Ask the slave device if they have any pending camera params changes (or wants to change something); |
|||
// Master sends: 1 byte: command id; |
|||
// Slave responds: 1 byte: |
|||
// bit 0: 0 - no change; 1 - wants to do some changes |
|||
|
|||
#define I2C_COMMAND_ID_CAMERA_CTRL_GET_PARAMS 0x51 |
|||
// Ask the slave device for the new camera params; |
|||
// Master sends: 1 byte: command id; |
|||
// Slave responds: 4 bytes: |
|||
// byte 0: brightness (0..100) |
|||
// byte 1: contrast (0..100) |
|||
// byte 2: saturation (0..100) |
|||
// byte 3: sharpness (0..100) |
|||
|
|||
#define I2C_COMMAND_ID_VIDEO_GET_QUALITY 0x55 |
|||
// Ask the slave device if they want to change the video quality |
|||
// Master sends: 1 byte: command id; |
|||
// Slave responds: 1 byte: |
|||
// bit 0: 0 - no (video quality is auto, decided by Ruby), 0-100 sets a custom video quality (0=lowest quality) |
|||
|
|||
|
|||
#define I2C_COMMAND_ID_PLAY_SOUND_ALARM 0x60 |
|||
// Ask the slave to play a particular sound |
|||
// Master sends: 2 bytes: command id; sound id: |
|||
// 1 - battery alarm; |
|||
// 2 - arm alarm; |
|||
// 3 - disarm alarm; |
|||
// Slave responds: 1 byte: |
|||
// bit 0: 0 - failed; 1 - succeeded; |
|||
|
|||
|
|||
// CRC table used for CRC calculations |
|||
const u8 s_crc_i2c_table[256] = { |
|||
0x00,0x31,0x62,0x53,0xC4,0xF5,0xA6,0x97,0xB9,0x88,0xDB,0xEA,0x7D,0x4C,0x1F,0x2E, |
|||
0x43,0x72,0x21,0x10,0x87,0xB6,0xE5,0xD4,0xFA,0xCB,0x98,0xA9,0x3E,0x0F,0x5C,0x6D, |
|||
0x86,0xB7,0xE4,0xD5,0x42,0x73,0x20,0x11,0x3F,0x0E,0x5D,0x6C,0xFB,0xCA,0x99,0xA8, |
|||
0xC5,0xF4,0xA7,0x96,0x01,0x30,0x63,0x52,0x7C,0x4D,0x1E,0x2F,0xB8,0x89,0xDA,0xEB, |
|||
0x3D,0x0C,0x5F,0x6E,0xF9,0xC8,0x9B,0xAA,0x84,0xB5,0xE6,0xD7,0x40,0x71,0x22,0x13, |
|||
0x7E,0x4F,0x1C,0x2D,0xBA,0x8B,0xD8,0xE9,0xC7,0xF6,0xA5,0x94,0x03,0x32,0x61,0x50, |
|||
0xBB,0x8A,0xD9,0xE8,0x7F,0x4E,0x1D,0x2C,0x02,0x33,0x60,0x51,0xC6,0xF7,0xA4,0x95, |
|||
0xF8,0xC9,0x9A,0xAB,0x3C,0x0D,0x5E,0x6F,0x41,0x70,0x23,0x12,0x85,0xB4,0xE7,0xD6, |
|||
0x7A,0x4B,0x18,0x29,0xBE,0x8F,0xDC,0xED,0xC3,0xF2,0xA1,0x90,0x07,0x36,0x65,0x54, |
|||
0x39,0x08,0x5B,0x6A,0xFD,0xCC,0x9F,0xAE,0x80,0xB1,0xE2,0xD3,0x44,0x75,0x26,0x17, |
|||
0xFC,0xCD,0x9E,0xAF,0x38,0x09,0x5A,0x6B,0x45,0x74,0x27,0x16,0x81,0xB0,0xE3,0xD2, |
|||
0xBF,0x8E,0xDD,0xEC,0x7B,0x4A,0x19,0x28,0x06,0x37,0x64,0x55,0xC2,0xF3,0xA0,0x91, |
|||
0x47,0x76,0x25,0x14,0x83,0xB2,0xE1,0xD0,0xFE,0xCF,0x9C,0xAD,0x3A,0x0B,0x58,0x69, |
|||
0x04,0x35,0x66,0x57,0xC0,0xF1,0xA2,0x93,0xBD,0x8C,0xDF,0xEE,0x79,0x48,0x1B,0x2A, |
|||
0xC1,0xF0,0xA3,0x92,0x05,0x34,0x67,0x56,0x78,0x49,0x1A,0x2B,0xBC,0x8D,0xDE,0xEF, |
|||
0x82,0xB3,0xE0,0xD1,0x46,0x77,0x24,0x15,0x3B,0x0A,0x59,0x68,0xFF,0xCE,0x9D,0xAC }; |
|||
|
|||
// CRC-8 function: |
|||
|
|||
/* |
|||
u8 calculate_i2c_crc(u8* pData, int iLength) |
|||
{ |
|||
u8 uCrc = 0xFF; |
|||
if ( NULL == pData || iLength <= 0 ) |
|||
return uCrc; |
|||
for ( int i = 0; i < iLength; i++) |
|||
uCrc = s_crc_i2c_table[pData[i] ^ uCrc]; |
|||
return uCrc; |
|||
} |
|||
*/ |
1063
src/main.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,256 @@ |
|||
#ifndef MAIN_H |
|||
#define MAIN_H |
|||
|
|||
// CPU NAMES |
|||
#define CPU_1 1 |
|||
#define CPU_0 0 |
|||
|
|||
// PINS |
|||
#define LED_INDICATOR 2 // Default LED light |
|||
#define BUTTON_SYNC 0 // Default Push Button |
|||
|
|||
// Mechanical Keyboard Toggle Switches |
|||
#define BUTTON1 18 |
|||
#define BUTTON2 19 |
|||
#define BUTTON3 25 |
|||
#define BUTTON4 26 |
|||
#define BUTTON5 27 |
|||
#define BUTTON6 14 |
|||
#define BUTTON7 12 |
|||
#define BUTTON8 13 |
|||
#define BUTTON9 4 |
|||
#define BUTTON10 5 |
|||
|
|||
// Gimbal |
|||
#define THROTTLE_PIN 36 |
|||
#define YAW_PIN 39 |
|||
#define PITCH_PIN 34 |
|||
#define ROLL_PIN 35 |
|||
#define RC_DEADBAND 5 |
|||
|
|||
// Voltage and Current Sense |
|||
#define V_SENSE_PIN 32 |
|||
#define A_SENSE_PIN 33 |
|||
|
|||
// OLED PIN |
|||
#define OLED_SDA 16 |
|||
#define OLED_SCL 17 |
|||
#define SCREEN_WIDTH 128 // OLED display width, in pixels |
|||
#define SCREEN_HEIGHT 64 // OLED display height, in pixels |
|||
|
|||
|
|||
// VERSION |
|||
#define VERSION_MAJOR 0 |
|||
#define VERSION_MINOR 0 |
|||
#define VERSION_BUILD 1 |
|||
|
|||
#include <Arduino.h> |
|||
// #include <EEPROM.h> |
|||
// #include "esp_wifi.h" |
|||
// #include <esp_now.h> |
|||
// #include <WiFi.h> |
|||
// #include "sbus.h" |
|||
#include <Wire.h> |
|||
#include <dummy.h> |
|||
#include "i2c_protocols.h" |
|||
|
|||
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"` |
|||
|
|||
|
|||
typedef struct struct_data { |
|||
uint8_t message_type; |
|||
uint16_t throttle; |
|||
uint16_t yaw; |
|||
uint16_t roll; |
|||
uint16_t pitch; |
|||
uint16_t aux; |
|||
// bool aux[9]; |
|||
// bool rubybutton[9]; |
|||
uint16_t rubybutton; |
|||
} struct_data; |
|||
|
|||
typedef struct sbus_data { |
|||
bool failsafe; |
|||
bool ch17; |
|||
bool ch18; |
|||
uint16_t ch[16]; |
|||
} struct_sbus; |
|||
|
|||
typedef struct struct_pairing { |
|||
uint8_t message_type; |
|||
uint8_t channel; |
|||
} struct_pairing; |
|||
|
|||
enum PairingStatus { |
|||
NOT_PAIRED, |
|||
PAIR_REQUEST, |
|||
PAIR_REQUESTED, |
|||
PAIR_PAIRED |
|||
}; |
|||
|
|||
enum MessageType { |
|||
PAIRING, |
|||
DATA, |
|||
COMMAND |
|||
}; |
|||
|
|||
enum ToggleButtonsName { |
|||
TOGGLE_A, |
|||
TOGGLE_B, |
|||
TOGGLE_C, |
|||
TOGGLE_D, |
|||
TOGGLE_E, |
|||
TOGGLE_F |
|||
}; |
|||
|
|||
enum MedianType { |
|||
VOLTAGE_POOL, |
|||
AMPERE_POOL, |
|||
THROTTLE_POOL, |
|||
YAW_POOL, |
|||
PITCH_POOL, |
|||
ROLL_POOL |
|||
}; |
|||
|
|||
// For Ground Station Pi via I2C |
|||
#define MAX_BUFFER_SIZE 1024 |
|||
#define I2C_SCL 22 |
|||
#define I2C_SDA 21 |
|||
#define I2C_SLAVE_ADDR 0x60 |
|||
|
|||
#define BUTTON_MENU 13 |
|||
#define BUTTON_BACK 12 |
|||
#define BUTTON_UP 14 |
|||
#define BUTTON_DOWN 27 |
|||
|
|||
|
|||
bool show_once = false; |
|||
bool header_detected = false; |
|||
uint8_t i2c_received[MAX_BUFFER_SIZE]; |
|||
uint8_t i2c_send[MAX_BUFFER_SIZE]; |
|||
uint16_t i2c_received_length = 0; |
|||
uint16_t i2c_send_length = 0; |
|||
uint8_t i2c_received_max = 0; |
|||
uint8_t frame_count = 0; |
|||
|
|||
uint8_t s_uRCChannelsOut[24]; |
|||
uint16_t s_iI2CLastCommandReadPosition = 0; |
|||
uint16_t s_iI2CLastCommandExpectedLength = 0; |
|||
uint8_t s_uI2CLastCommandBuff[MAX_BUFFER_SIZE]; |
|||
uint8_t s_uI2CLastResponseBuff[MAX_BUFFER_SIZE]; |
|||
int16_t s_iI2CLastResponseSentPosition = -1; |
|||
uint16_t s_iI2CLastResponseLength = 0; |
|||
bool rubybutton[16]; |
|||
uint32_t rubybutton_last[16]; |
|||
uint16_t rubybutton_delay = 100; |
|||
|
|||
|
|||
#define DEFAULT_CHANNEL 1 |
|||
#define EEPROM_SIZE 7 // define the number of bytes you want to access |
|||
|
|||
/* SBUS data */ |
|||
// bfs::SbusData sbus_data; |
|||
// bfs::SbusTx sbus_tx(&Serial2, 16, 17, true, false); |
|||
/*** |
|||
SbusTx(HardwareSerial *bus, const int8_t rxpin, const int8_t txpin, |
|||
const bool inv) : uart_(bus), inv_(inv), rxpin_(rxpin), txpin_(txpin) |
|||
****/ |
|||
bool signalNotOK = false; |
|||
bool i2c_status = false; |
|||
uint16_t i2c_counter = 0; |
|||
uint16_t i2c_counter_raw = 0; |
|||
|
|||
uint32_t last_sent = 0; |
|||
bool sync_mode = false; |
|||
struct_data incomingReadings; |
|||
struct_pairing pairingData; |
|||
struct_sbus sbusData; |
|||
|
|||
/// uint8_t broadcast_address[] = { 0x78, 0x21, 0x84, 0x8d, 0xd9, 0x38 }; |
|||
uint8_t broadcast_address[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
|||
uint8_t allow_address[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
|||
|
|||
uint8_t frame_count_raw = 0; |
|||
int16_t counter_raw = 0; |
|||
int16_t counter = 0; |
|||
uint16_t voltage_steps = 0; |
|||
uint16_t current_steps = 0; |
|||
uint16_t throttle_steps = 0; |
|||
uint16_t yaw_steps = 0; |
|||
uint16_t roll_steps = 0; |
|||
uint16_t pitch_steps = 0; |
|||
uint16_t throttle_val = 0; |
|||
uint16_t throttle_val_tmp = 0; |
|||
uint16_t yaw_val = 0; |
|||
uint16_t yaw_val_tmp = 0; |
|||
uint16_t pitch_val = 0; |
|||
uint16_t pitch_val_tmp = 0; |
|||
uint16_t roll_val = 0; |
|||
uint16_t roll_val_tmp = 0; |
|||
|
|||
// Active calibration |
|||
uint16_t min_throttle = 1000; |
|||
uint16_t max_throttle = 1800; |
|||
uint16_t min_yaw = 1800; |
|||
uint16_t max_yaw = 1000; |
|||
uint16_t min_pitch = 1800; |
|||
uint16_t max_pitch = 1000; |
|||
uint16_t min_roll = 1800; |
|||
uint16_t max_roll = 1000; |
|||
uint16_t gimbal_rate = 0; |
|||
|
|||
|
|||
#define MEDIAN_TOTAL 11 |
|||
#define MEDIAN_POS MEDIAN_TOTAL/2 |
|||
uint16_t pool_voltage[MEDIAN_TOTAL]; |
|||
uint16_t median_voltage(uint16_t val); |
|||
uint16_t median_get_voltage_steps(void); |
|||
#define VOLTAGE_MULTIPLER .0049146189 |
|||
|
|||
uint16_t raw_throttle, raw_yaw, raw_pitch, raw_roll; |
|||
uint16_t pool_throttle[MEDIAN_TOTAL]; |
|||
uint16_t pool_yaw[MEDIAN_TOTAL]; |
|||
uint16_t pool_pitch[MEDIAN_TOTAL]; |
|||
uint16_t pool_roll[MEDIAN_TOTAL]; |
|||
uint16_t median_throttle(uint16_t val); |
|||
uint16_t median_get_throttle_steps(void); |
|||
uint16_t median_yaw(uint16_t val); |
|||
uint16_t median_get_yaw_steps(void); |
|||
uint16_t median_pitch(uint16_t val); |
|||
uint16_t median_get_pitch_steps(void); |
|||
uint16_t median_roll(uint16_t val); |
|||
uint16_t median_get_roll_steps(void); |
|||
uint16_t median(uint8_t median_type); |
|||
#define MAX_SAMPLING 5 |
|||
#define POS_SAMPLING MAX_SAMPLING / 2 |
|||
uint16_t sampling(uint8_t median_type); |
|||
uint16_t sampling_data[MAX_SAMPLING]; |
|||
uint16_t key; |
|||
uint8_t i, j; |
|||
uint16_t profile_gimbal_rate; |
|||
uint16_t profile_gimbal_rate_raw; |
|||
|
|||
|
|||
|
|||
// Controller Toggle Buttons and Gimbal |
|||
bool toggle_buttons[6]; |
|||
|
|||
// Task Handler |
|||
// void taskScreen(void *pvParameters); |
|||
// void taskSpeak(void *pvParameters); |
|||
void taskButton(void *pvParameters); |
|||
void taskCounter(void *pvParameters); |
|||
void taskDisplay(void *pvParameters); |
|||
void taskSystemStatus(void *pvParameters); |
|||
void taskGimbal(void *pvParameters); |
|||
// void taskSBUS(void *pvParameters); |
|||
|
|||
// Functions |
|||
void printMAC(const uint8_t * mac_addr); |
|||
//// void initESP_NOW(); |
|||
void onI2C0Receive(int len); |
|||
void onI2C0Request(void); |
|||
void parse_i2c_command(void); |
|||
void display_info(void); |
|||
|
|||
#endif |
@ -0,0 +1,11 @@ |
|||
|
|||
This directory is intended for PlatformIO Test Runner and project tests. |
|||
|
|||
Unit Testing is a software testing method by which individual units of |
|||
source code, sets of one or more MCU program modules together with associated |
|||
control data, usage procedures, and operating procedures, are tested to |
|||
determine whether they are fit for use. Unit testing finds problems early |
|||
in the development cycle. |
|||
|
|||
More information about PlatformIO Unit Testing: |
|||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html |
Write
Preview
Loading…
Cancel
Save
Reference in new issue