Merge branch 'arendst:development' into development

This commit is contained in:
Alexey Pavlov 2021-12-20 19:33:53 +03:00 committed by GitHub
commit 2f7365ccf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
325 changed files with 7168 additions and 2752 deletions

2
.gitpod.Dockerfile vendored
View File

@ -2,4 +2,4 @@ FROM gitpod/workspace-full
USER gitpod
RUN pip3 install -U platformio && brew install uncrustify
RUN pip3 install -U platformio

View File

@ -893,6 +893,7 @@ All notable changes to this project will be documented in this file.
### Changed
- Triple-mode TLS via configuration in a single firmware (TLS AWS IoT, Letsencrypt and No-TLS)
- Berry C mapping moved to a separate ``berry_mapping`` library
### Fixed
- ESP32 PWM range

View File

@ -208,4 +208,3 @@ void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data)
digitalWrite(SPI_CS,HIGH);
}

View File

@ -187,4 +187,3 @@ class LedControl {
#endif //LedControl.h

View File

@ -0,0 +1,422 @@
/*
* LedMatrix.h - Extends the Library LedControl for multiple 8x8 LED dot matrix maxDevices, based on MAX7219/MAX7221
* Copyright (c) 2021 Michael Beuss
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* This permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "LedMatrix.h"
#include "font_6x8_base.h"
//#include "font_6x8_UTF8_C2.h" // additional characters if needed
//#include "font_6x8_UTF8_C3.h" // additional characters (latin1) if needed
#include "../../../../tasmota/my_user_config.h" // to check compiler option USE_UTF8_LATIN1
#ifdef USE_UTF8_LATIN1
#include "font_6x8_UTF8_C2.h" // 256 bytes
#include "font_6x8_UTF8_C3.h" // 512 bytes
#endif
//the opcodes for the MAX7221 and MAX7219
#define OP_NOOP 0
#define OP_DIGIT0 1
#define OP_DIGIT1 2
#define OP_DIGIT2 3
#define OP_DIGIT3 4
#define OP_DIGIT4 5
#define OP_DIGIT5 6
#define OP_DIGIT6 7
#define OP_DIGIT7 8
#define OP_DECODEMODE 9
#define OP_INTENSITY 10
#define OP_SCANLIMIT 11
#define OP_SHUTDOWN 12
#define OP_DISPLAYTEST 15
LedMatrix::LedMatrix(int dataPin, int clkPin, int csPin, unsigned int colums, unsigned int rows)
{
if (colums * rows > MAX72XX_MAX_DEVICES)
{
// dimension exeeds maximum buffer size
if (colums >= MAX72XX_MAX_DEVICES)
{
colums = MAX72XX_MAX_DEVICES;
rows = 1;
}
else
{
rows = MAX72XX_MAX_DEVICES / colums;
}
}
charWidth = font_char_width; // defined in header file of font
charHeight = font_char_height; // defined in header file of font
modulesPerRow = colums;
modulesPerCol = rows;
displayWidth = colums * 8;
displayHeight = rows * 8;
maxDevices = colums * rows;
moduleOrientation = ORIENTATION_UPSIDE_DOWN; // use setOrientation() to turn it
textBuf[0] = 0;
textWidth = 0;
textPosX = 0;
textPosY = 0;
appendTextBuf[0] = 0;
setScrollAppendText(" ");
powerIsOn = false;
// initialize all connected MAX7219/MAX7221 devices
SPI_MOSI = dataPin;
SPI_CLK = clkPin;
SPI_CS = csPin;
pinMode(SPI_MOSI, OUTPUT);
pinMode(SPI_CLK, OUTPUT);
pinMode(SPI_CS, OUTPUT);
SPI_MOSI = dataPin;
//spiTransfer_value(OP_DISPLAYTEST, 0); // display test
spiTransfer_value(OP_SCANLIMIT, 7); // scanlimit is set to max on startup
spiTransfer_value(OP_DECODEMODE, 0); // decode is done in source
clearDisplay();
//spiTransfer_value(OP_SHUTDOWN, 0); //we go into shutdown-mode (LEDs off) on startup
setIntensity(7); // initialize with the half of the maximum intensity [0..15]
power(true); // power on;
}
bool LedMatrix::drawText( const char *str, bool clearBefore)
{
if(clearBefore) clearDisplay();
strncpy(textBuf, str, TEXT_BUFFER_SIZE -1);
textPosX = 0;
textPosY = 0;
textLen = countChars(str);
textWidth = textLen * charWidth;
if(textWidth <= displayWidth)
{
// text fits into the display, place it into the center
textPosX = (displayWidth - textWidth) / 2; // center
}
else
{
// The text ist longer than the display width. Scrolling is needed.
// Add a space in front of text to have a distance to the pervious scroll text.
addSpace();
}
drawTextAt(textBuf, textPosX, textPosY);
refresh(); // refresh display with the new drawed string content
return true;
}
bool LedMatrix::drawTextAt( const char *str, const int x, const int y )
{
// draw character by character
int xPos = x;
const char* fontChar = nullptr;
for (unsigned int i = 0; (i<TEXT_BUFFER_SIZE && str[i]!=0); i++)
{
char c = str[i];
fontChar = font_20_7F[char('_') - 0x20]; // default character in case of non printable or undefined
if( c >= 0x20 && c < 0x80) // basic font
{
fontChar = font_20_7F[c-0x20];
}
#ifdef font_6x8_UTF8_C2_h
else if(c == 0xC2) // UTF special characters
{
i++;
c= str[i];
if(c>= 0xA0 && c < 0xC0)
{
fontChar = font_UTF_C2_A0_BF[c - 0xA0];
}
}
#endif // font_6x8_UTF8_C2_h
#ifdef font_6x8_UTF8_C3_h
else if(c == 0xC3) // UTF latin1
{
i++;
c= str[i];
if(c>= 0x80 && c < 0xC0)
{
fontChar = font_UTF_C3_80_BF[c - 0x80];
}
}
#endif // font_6x8_UTF8_C3_h
else if(c>= 0xC0 && c <= 0xDF)
{
i += 1; // 2 byte UTF sequence
}
else if(c>= 0xE0 && c <= 0xEF)
{
i += 2; // 3 byte UTF sequence
}
else if(c>= 0xF0 && c <= 0xF7)
{
i += 3; // 4 byte UTF sequence
}
drawCharAt(fontChar, xPos, y);
xPos += charWidth;
}
return true;
}
int LedMatrix::countChars( const char* utfText)
{
int len = 0;
for( int i = 0; (i<TEXT_BUFFER_SIZE && utfText[i]!=0); i++)
{
char c = utfText[i];
if( c < 0xC0)
{
// 1 byte UTF sequence
}
else if(c <= 0xDF)
{
i += 1; // 2 byte UTF sequence
}
else if(c <= 0xEF)
{
i += 2; // 3 byte UTF sequence
}
else if(c <= 0xF7)
{
i += 3; // 4 byte UTF sequence
}
len++;
}
return len;
}
bool LedMatrix::scrollText()
{
if(textWidth <= displayWidth) return false; // do not scroll when text fits into the display
textPosX--;
if(textPosX + textWidth < (int)0)
{
textPosX = 0; // start from the beginning after text scrolled out of display;
}
drawTextAt(textBuf, textPosX, textPosY);
int startOfRepeatingTextPos = textPosX + textWidth;
if(startOfRepeatingTextPos < displayWidth)
{
// draw repeating text
drawTextAt(textBuf, startOfRepeatingTextPos, textPosY);
}
refresh();
return true;
}
void LedMatrix::power(bool on)
{
powerIsOn = on;
byte value = 0; // 0: shutdown
if(on) value = 1; // 1: power on
spiTransfer_value(OP_SHUTDOWN, value); // power(false) shuts down the display
}
bool LedMatrix::isPowerOn()
{
return powerIsOn;
}
bool LedMatrix::clearDisplay(void)
{
memset(textBuf, 0, TEXT_BUFFER_SIZE);
textWidth = 0;
memset(buffer, 0, MATRIX_BUFFER_SIZE);
for (int row = 0; row < 8; row++)
{
spiTransfer_value(row + 1, 0);
}
return true;
}
bool LedMatrix::setIntensity(byte intensity)
{
if (intensity < 0 || intensity > 15)
return false;
spiTransfer_value(OP_INTENSITY, intensity);
return true;
}
bool LedMatrix::setOrientation(LedMatrix::ModuleOrientation orientation)
{
if(moduleOrientation != orientation)
{
moduleOrientation = orientation;
refresh();
}
return true;
}
bool LedMatrix::setScrollAppendText(const char* append )
{
strncpy(appendTextBuf, append, TEXT_APPEND_BUFFER_SIZE -1);
return (strlen(append) < TEXT_APPEND_BUFFER_SIZE);
}
bool LedMatrix::setPixel(const int x, const int y, bool on)
{
if (x >= displayWidth || y >= displayHeight)
return false;
int modul_col = x / 8; // x pos divided by 8 is the index of the modul to the right
int buffer_pos = modul_col + y * modulesPerRow;
byte buffer_byte = 0x80 >> (x % 8);
if (on)
{
buffer[buffer_pos] |= buffer_byte; // set bit
}
else
{
buffer[buffer_pos] &= ~buffer_byte; // reset bit
}
return true;
}
void LedMatrix::refresh()
{
int col = 0;
int pixelRow = 0;
int bufPos = 0;
int deviceRow = 0;
for(int ledRow = 7; ledRow >= 0; ledRow--) // refresh from buttom to top
{
for( int addr = 0; addr < maxDevices; addr++)
{
if(moduleOrientation == ORIENTATION_NORMAL || moduleOrientation == ORIENTATION_UPSIDE_DOWN)
{
col = addr % modulesPerRow;
pixelRow = (addr / modulesPerRow) * 8 + ledRow;
bufPos = pixelRow * modulesPerRow + col;
if(moduleOrientation == ORIENTATION_NORMAL)
{
// ORIENTATION_NORMAL
deviceDataBuff[addr] = revereBitorder(buffer[bufPos]); // mirror
deviceRow = 7 - ledRow; // upside down
}
else
{
// ORIENTATION_UPSIDE_DOWN
deviceDataBuff[maxDevices -1 - addr] = buffer[bufPos];
deviceRow = ledRow;
}
}
else // ORIENTATION_TURN_RIGHT || ORIENTATION_TURN_LEFT
{
// not implemented yet
}
}
setRow_allDevices(deviceRow, deviceDataBuff);
}
}
// private functions
/**
* @brief
*
* @param fontChar defines the pixelrows of a character. const char fontChar[charHeight]
* @param x
* @param y
*/
bool LedMatrix::drawCharAt( const char* fontChar, const int x, const int y)
{
// ignore when the character position is not visible on the display
bool visible = (
x > 0 - (int)charWidth && x < (int)displayWidth &&
y > 0 - (int)charHeight && y < (int)displayHeight
);
if (!visible) return false;
// ignore the leading bits above charWidth of the font definition
static const byte charOffset = 8 - charWidth;
for (byte charY = 0; charY < charHeight; charY++)
{
char pixelRow = (fontChar[charY]) << charOffset; // skip the first bits when the character width is smaller than 8 pixel
for (byte charX = 0; charX < charWidth; charX++)
{
bool pixel = (pixelRow & 0x80); // pixel=true when upper bit is set
setPixel(x + charX, y + charY, pixel);
pixelRow = pixelRow << 1; // next pixel
}
}
return true;
}
byte LedMatrix::revereBitorder (byte b)
{
static const byte lookup[16] = {
0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
};
return (lookup[b & 0b1111] << 4) | lookup[b >> 4];
}
void LedMatrix::addSpace()
{
strncat(textBuf, appendTextBuf, TEXT_BUFFER_SIZE -1);
textPosX = strlen(appendTextBuf) * charWidth; // start scrolling with space
textLen = countChars(textBuf);
textWidth = countChars(textBuf) * charWidth;
}
void LedMatrix::setRow_allDevices(int row, byte *data)
{
if (row < 0 || row > 7)
return;
spiTransfer_array(row + 1, data);
}
void LedMatrix::spiTransfer_array(byte opcode, const byte* data) {
// create an array with the data to shift out
for (int addr = 0; addr < maxDevices; addr++)
{
spidata[addr * 2 + 1] = opcode;
spidata[addr * 2] = data[addr];
}
// enable the line
digitalWrite(SPI_CS, LOW);
// shift out the data
for (int i = maxDevices * 2 -1; i >= 0; i--)
{
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, spidata[i]);
}
// latch the data onto the display
digitalWrite(SPI_CS, HIGH);
}
void LedMatrix::spiTransfer_value(byte opcode, byte value)
{
memset(deviceDataBuff, (byte)value, maxDevices);
spiTransfer_array(opcode, deviceDataBuff);
}

View File

@ -0,0 +1,211 @@
/*
* LedMatrix.h - Extends the Library LedControl for multiple 8x8 LED dot matrix devices, based on MAX7219/MAX7221
* Copyright (c) 2021 Michael Beuss
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* This permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef LedMatrix_h
#define LedMatrix_h
#include <pgmspace.h>
#if (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#ifndef MAX72XX_MAX_DEVICES
#define MAX72XX_MAX_DEVICES 32 // maximum number of devices based on MXA7219/MAX7221
#endif
#define MATRIX_BUFFER_SIZE MAX72XX_MAX_DEVICES * 8 // 8 bytes per modul. One byte represents 8 LEDs.
#define TEXT_BUFFER_SIZE 256 // maximum text length that can be scrolled
#define TEXT_APPEND_BUFFER_SIZE 16 // used for characters that are appended to the scroll text, before it repeats
#define SPI_BUFFER_SIZE MAX72XX_MAX_DEVICES * 2 // buffer size fort shifting commands to all devices (2 bytes each)
/**
* @brief LedMatrix controls multiple 8x8 LED dot matrx devices.
* All devices in rows and clolums together build a common display pixel matrix.
*
*/
class LedMatrix
{
public:
enum ModuleOrientation // orientation of 8x8 LED dot matrix mdules (first module starts at top left)
{
ORIENTATION_NORMAL, // first pixel is on top left, no turn is necessary
ORIENTATION_TURN_RIGHT, // first pixel is on bottom left, for correction it has to turn 90° right
ORIENTATION_UPSIDE_DOWN, // first pixel is on bottom right, fpr correction it has to turn 180°
ORIENTATION_TURN_LEFT, // first pixel is on top right, for correction is has to turn 90° left.
};
public:
/**
* @brief Construct a new LED Matrix object
*
* @param colums of 8x8 LED dot matrix devices
* @param rows of 8x8 LED dot matrix devices
*/
LedMatrix(int dataPin, int clkPin, int csPin, unsigned int colums, unsigned int rows);
/**
* @brief Draws a string to the display.
* When the text fits into the display, it will be shown in the center.
* When the text is longer than than the display width, it can be scrolled per pixel with function scrollText().
*
* @param str string to display
* @param clearBefore true (default) clears old display content before, false: do not clear display before
*/
bool drawText( const char *str, bool clearBefore = true );
/**
* @brief Dwaws a character string to a defined display position. The position (x,y) is used for the upper left pixel of the text.
* Existing content outside the drawing text area will not be cleared. But you can use clearDisplay() before.
* Use refresh() after all text parts are drawed.
*
* @param str string to display
* @param x horizantal pixel position to start with string (0 is most left)
* @param y vertical pixel position for the top position of the string (0 is top)
*/
bool drawTextAt( const char *str, const int x, const int y );
/**
* @brief Scroll the current text one pixel to the left.
* Repeat with from start when end of text reached. This function can be called every 50 ms to get a propper scroll speed.
*
*/
bool scrollText();
/**
* @brief switches the display on or off
*
* @param on true: on false: off
*/
void power( bool on );
bool isPowerOn();
/**
* @brief cleares the display and text buffer
*
*/
bool clearDisplay(void);
/**
* @brief Set the brightness of the display
*
* @param dim 0..15 (0: dark .. 15: light)
*/
bool setIntensity(byte dim);
/**
* @brief Set the orientation of the 8x8 LED dot matrix module
*
* @param orientation
*/
bool setOrientation(LedMatrix::ModuleOrientation orientation);
/**
* @brief Set ap pixel at a defined position.
* After all Pixels are set, call refresh() to send it to the display.
*
* @param x horizontal position from left
* @param y vertical position from top
* @param on true: on, false: off
*/
/**
* @brief Adds a string before the scrolling text to set a distance. Usually some spaces are used.
*
* @param append text to append to the scrolling text before repeating.
*/
bool setScrollAppendText(const char* append );
bool setPixel( const int x, const int y, bool on=true);
/**
* @brief sends the changed content of the buffer to the display
*
*/
void refresh();
private:
bool drawCharAt( const char* fontChar, int x, int y ); // Draws a character to a defined position
int countChars( const char* utfText); // count the characters of an UTF8 string. To be uesd instead of strlen().
byte revereBitorder(byte b); // returnes the byte in the reverse bit order.
void addSpace(); // adds characters in front of the text to get a distance to the repeating scroll text
// device contrl MAX7219/MAX7221
/**
* @brief Set data for the same row of all devices
*
* @param row [0..8]
* @param value array of bytes, one for each device
*/
void setRow_allDevices(int row, byte* value);
/* Send out a command with the same opcode to all devices */
/**
* @brief sends opcode with specific data values to each device
*
* @param opcode
* @param data array of byte values (data[0] is the value for the first device)
*/
void spiTransfer_array(byte opcode, const byte* data);
/**
* @brief sends opcode with same value to all devices
*/
void spiTransfer_value(byte opcode, byte value);
private:
int SPI_MOSI; // Data is shifted out of this pin
int SPI_CLK; // The clock is signaled on this pin
int SPI_CS; // This one is driven LOW for chip selectzion
unsigned int modulesPerRow;
unsigned int modulesPerCol;
unsigned int displayWidth; // matrix width [pixel]
unsigned int displayHeight; // matrix height [pixel]
int maxDevices; // number of used 8x8 devices
uint8_t moduleOrientation;
byte buffer[MATRIX_BUFFER_SIZE];
byte deviceDataBuff[MAX72XX_MAX_DEVICES];
int charWidth;
int charHeight;
char textBuf[TEXT_BUFFER_SIZE];
char appendTextBuf[TEXT_APPEND_BUFFER_SIZE];
int textLen; // number of UTF8 characters
int textWidth; // width of text [pixel]
int textPosX; // horizontal pixel position of scrolling text
int textPosY; // vertical pixelposition of scrolling text;
byte spidata[SPI_BUFFER_SIZE]; // The array for shifting the data to the devices
bool powerIsOn;
};
#endif //LedMatrix_h

View File

@ -0,0 +1,340 @@
// 6x8 ascii font
#ifndef font_6x8_UTF8_C2_h
#define font_6x8_UTF8_C2_h
/**
* additional characters to font_6x8_base.h
* 256 bytes
*
*/
/*
UTF8 after 0xC2
0 1 2 3 4 5 6 7 8 9 A B C D E F
A NBSP¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ SHY ® ¯
B ° ± ² ³ ´ µ · ¸ ¹ º » ¼ ½ ¾ ¿
*/
const char font_UTF_C2_A0_BF[0xC0-0xA0][8] = {
{
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x80 NBSP
{
0b00000100,
0b00000000,
0b00000100,
0b00000100,
0b00001110,
0b00001110,
0b00000100,
0b00000000,
}, // 0x81 ¡
{
0b00000000,
0b00000100,
0b00001110,
0b00010000,
0b00010000,
0b00001110,
0b00000100,
0b00000000,
}, // 0x82 ¢
{
0b00000110,
0b00001001,
0b00001000,
0b00011110,
0b00001000,
0b00001001,
0b00010111,
0b00000000,
}, // 0x83 £
{
0b00010001,
0b00001110,
0b00010001,
0b00010001,
0b00010001,
0b00001110,
0b00010001,
0b00000000,
}, // 0x84 ¤
{
0b00010001,
0b00001010,
0b00000100,
0b00011111,
0b00000100,
0b00011111,
0b00000100,
0b00000000,
}, // 0x85 ¥
{
0b00000100,
0b00000100,
0b00000100,
0b00000000,
0b00000100,
0b00000100,
0b00000100,
0b00000000,
}, // 0x86 ¦
{
0b00001110,
0b00010001,
0b00001100,
0b00001010,
0b00000110,
0b00010001,
0b00001110,
0b00000000,
}, // 0x87 §
{
0b00000000,
0b00000000,
0b00000000,
0b00001010,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x88 ¨
{
0b00011110,
0b00100001,
0b00101101,
0b00101001,
0b00101101,
0b00100001,
0b00011110,
0b00000000,
}, // 0x89 ©
{
0b00001110,
0b00000001,
0b00001111,
0b00010001,
0b00001111,
0b00000000,
0b00001111,
0b00000000,
}, // 0x8A ª
{
0b00000000,
0b00000000,
0b00001001,
0b00010010,
0b00001001,
0b00000000,
0b00000000,
0b00000000,
}, // 0x8B «
{
0b00000000,
0b00000000,
0b00111111,
0b00000001,
0b00000001,
0b00000000,
0b00000000,
0b00000000,
}, // 0x8C ¬
{
0b00000000,
0b00000000,
0b00000000,
0b00000001,
0b00000001,
0b00000000,
0b11111111,
0b00000000,
}, // 0x8D SHY
{
0b00011110,
0b00100101,
0b00101011,
0b00101101,
0b00101011,
0b00100001,
0b00011110,
0b00000000,
}, // 0x8E ®
{
0b00000000,
0b00001110,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x8F ¯
{
0b00001100,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x90 °
{
0b00000000,
0b00000100,
0b00001110,
0b00000100,
0b00000000,
0b00001110,
0b00000000,
0b00000000,
}, // 0x91 ±
{
0b00011000,
0b00000100,
0b00001000,
0b00011100,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x92 ²
{
0b00011100,
0b00001000,
0b00001100,
0b00011000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x93 ³
{
0b00001100,
0b00001100,
0b00001000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x94 ´
{
0b00000000,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00011100,
0b00010000,
0b00010000,
}, // 0x95 µ
{
0b00001111,
0b00010101,
0b00010101,
0b00001101,
0b00000101,
0b00000101,
0b00000101,
0b00000000,
}, // 0x96 ¶
{
0b00000000,
0b00000000,
0b00000000,
0b00001000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x97 ·
{
0b00000000,
0b00000000,
0b00000000,
0b00001110,
0b00000110,
0b00000000,
0b00000000,
0b00000000,
}, // 0x98 ¸
{
0b00001000,
0b00011000,
0b00001000,
0b00001000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x99 ¹
{
0b00001100,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
0b00011110,
0b00000000,
}, // 0x9A º
{
0b00000000,
0b00000000,
0b00010010,
0b00001001,
0b00010010,
0b00000000,
0b00000000,
0b00000000,
}, // 0x9B »
{
0b00010000,
0b00010010,
0b00010100,
0b00001011,
0b00010101,
0b00000111,
0b00000001,
0b00000000,
}, // 0x9C ¼
{
0b00010000,
0b00010010,
0b00010100,
0b00001110,
0b00010001,
0b00000010,
0b00000111,
0b00000000,
}, // 0x9D ½
{
0b00110000,
0b00011010,
0b00110100,
0b00001011,
0b00010101,
0b00000111,
0b00000001,
0b00000000,
}, // 0x9E ¾
{
0b00000100,
0b00000000,
0b00000100,
0b00001100,
0b00010000,
0b00010001,
0b00001110,
0b00000000,
}, // 0x9F ¿
};
#endif // font_6x8_UTF8_C2_h

View File

@ -0,0 +1,678 @@
// 6x8 ascii font
#ifndef font_6x8_UTF8_C3_h
#define font_6x8_UTF8_C3_h
/**
* additional characters to font_6x8_base.h
* 512 bytes
*
*/
/*
UTF8 after 0xC3
0 1 2 3 4 5 6 7 8 9 A B C D E F
8 À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï
9 Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß
A à á â ã ä å æ ç è é ê ë ì í î ï
B ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ
*/
const char font_UTF_C3_80_BF[0xC0-0x80][8] = {
{
0b00001100,
0b00000000,
0b00000100,
0b00001010,
0b00010001,
0b00011111,
0b00010001,
0b00000000,
}, // 0x80 À
{
0b00000110,
0b00000000,
0b00000100,
0b00001010,
0b00010001,
0b00011111,
0b00010001,
0b00000000,
}, // 0x81 Á
{
0b00001110,
0b00000000,
0b00000100,
0b00001010,
0b00010001,
0b00011111,
0b00010001,
0b00000000,
}, // 0x82 Â
{
0b00000101,
0b00001010,
0b00000100,
0b00001010,
0b00010001,
0b00011111,
0b00010001,
0b00000000,
}, // 0x83 Ã
{
0b00001010,
0b00000000,
0b00000100,
0b00001010,
0b00010001,
0b00011111,
0b00010001,
0b00000000,
}, // 0x84 Ä
{
0b00001110,
0b00001010,
0b00001110,
0b00011011,
0b00010001,
0b00011111,
0b00010001,
0b00000000,
}, // 0x85 Å
{
0b00000111,
0b00001100,
0b00010100,
0b00010111,
0b00011100,
0b00010100,
0b00010111,
0b00000000,
}, // 0x86 Æ
{
0b00001110,
0b00010001,
0b00010000,
0b00010000,
0b00010001,
0b00001110,
0b00000100,
0b00001100,
}, // 0x87 Ç
{
0b00001100,
0b00000000,
0b00011111,
0b00010000,
0b00011110,
0b00010000,
0b00011111,
0b00000000,
}, // 0x88 È
{
0b00000011,
0b00000000,
0b00011111,
0b00010000,
0b00011110,
0b00010000,
0b00011111,
0b00000000,
}, // 0x89 É
{
0b00001110,
0b00000000,
0b00011111,
0b00010000,
0b00011110,
0b00010000,
0b00011111,
0b00000000,
}, // 0x8A Ê
{
0b00001010,
0b00000000,
0b00011111,
0b00010000,
0b00011110,
0b00010000,
0b00011111,
0b00000000,
}, // 0x8B Ë
{
0b00001100,
0b00000000,
0b00001110,
0b00000100,
0b00000100,
0b00000100,
0b00001110,
0b00000000,
}, // 0x8C Ì
{
0b00000110,
0b00000000,
0b00001110,
0b00000100,
0b00000100,
0b00000100,
0b00001110,
0b00000000,
}, // 0x8D Í
{
0b00001110,
0b00000000,
0b00001110,
0b00000100,
0b00000100,
0b00000100,
0b00001110,
0b00000000,
}, // 0x8E Î
{
0b00001010,
0b00000000,
0b00001110,
0b00000100,
0b00000100,
0b00000100,
0b00001110,
0b00000000,
}, // 0x8F Ï
{
0b00001110,
0b00001001,
0b00001001,
0b00011101,
0b00001001,
0b00001001,
0b00001110,
0b00000000,
}, // 0x90 Ð
{
0b00001010,
0b00010100,
0b00000000,
0b00010010,
0b00011010,
0b00010110,
0b00010010,
0b00000000,
}, // 0x91 Ñ
{
0b00011000,
0b00001100,
0b00010010,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0x92 Ò
{
0b00000110,
0b00001100,
0b00010010,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0x93 Ó
{
0b00001110,
0b00001100,
0b00010010,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0x94 Ô
{
0b00001010,
0b00010100,
0b00001100,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0x95 Õ
{
0b00010010,
0b00001100,
0b00010010,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0x96 Ö
{
0b00000000,
0b00010001,
0b00001010,
0b00000100,
0b00001010,
0b00010001,
0b00000000,
0b00000000,
}, // 0x97 ×
{
0b00001111,
0b00010011,
0b00010101,
0b00010101,
0b00010101,
0b00011001,
0b00011110,
0b00000000,
}, // 0x98 Ø
{
0b00011000,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0x99 Ù
{
0b00000110,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0x9A Ú
{
0b00001110,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0x9B Û
{
0b00001010,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0x9C Ü
{
0b00000110,
0b00000000,
0b00010001,
0b00001010,
0b00000100,
0b00000100,
0b00000100,
0b00000000,
}, // 0x9D Ý
{
0b00011000,
0b00010000,
0b00011100,
0b00010010,
0b00010010,
0b00011100,
0b00010000,
0b00011000,
}, // 0x9E Þ
{
0b00000000,
0b00011100,
0b00010010,
0b00011100,
0b00010010,
0b00010010,
0b00011100,
0b00010000,
}, // 0x9F ß
{
0b00001100,
0b00000000,
0b00001110,
0b00000001,
0b00001111,
0b00010001,
0b00001111,
0b00000000,
}, // 0xA0 à
{
0b00000110,
0b00000000,
0b00001110,
0b00000001,
0b00001111,
0b00010001,
0b00001111,
0b00000000,
}, // 0xA1 á
{
0b00001110,
0b00000000,
0b00001110,
0b00000001,
0b00001111,
0b00010001,
0b00001111,
0b00000000,
}, // 0xA2 â
{
0b00000101,
0b00001010,
0b00001110,
0b00000001,
0b00001111,
0b00010001,
0b00001111,
0b00000000,
}, // 0xA3 ã
{
0b00001010,
0b00000000,
0b00001110,
0b00000001,
0b00001111,
0b00010001,
0b00001111,
0b00000000,
}, // 0xA4 ä
{
0b00001110,
0b00001010,
0b00001110,
0b00000001,
0b00001111,
0b00010001,
0b00001111,
0b00000000,
}, // 0xA5 å
{
0b00000000,
0b00000000,
0b00011110,
0b00000101,
0b00011111,
0b00010100,
0b00001111,
0b00000000,
}, // 0xA6 æ
{
0b00000000,
0b00001110,
0b00010001,
0b00010000,
0b00010001,
0b00001110,
0b00000100,
0b00001100,
}, // 0xA7 ç
{
0b00001100,
0b00000000,
0b00001110,
0b00010001,
0b00011110,
0b00010000,
0b00001110,
0b00000000,
}, // 0xA8 è
{
0b00000011,
0b00000000,
0b00001110,
0b00010001,
0b00011110,
0b00010000,
0b00001110,
0b00000000,
}, // 0xA9 é
{
0b00001110,
0b00000000,
0b00001110,
0b00010001,
0b00011110,
0b00010000,
0b00001110,
0b00000000,
}, // 0xAA ê
{
0b00001010,
0b00000000,
0b00001110,
0b00010001,
0b00011110,
0b00010000,
0b00001110,
0b00000000,
}, // 0xAB ë
{
0b00001000,
0b00000000,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000110,
0b00000000,
}, // 0xAC ì
{
0b00000110,
0b00000000,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000110,
0b00000000,
}, // 0xAD í
{
0b00000110,
0b00000000,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000110,
0b00000000,
}, // 0xAE î
{
0b00001010,
0b00000000,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000110,
0b00000000,
}, // 0xAF ï
{
0b00001100,
0b00010000,
0b00001000,
0b00000100,
0b00001110,
0b00010010,
0b00001100,
0b00000000,
}, // 0xB0 ð
{
0b00001010,
0b00010100,
0b00000000,
0b00011100,
0b00010010,
0b00010010,
0b00010010,
0b00000000,
}, // 0xB1 ñ
{
0b00011000,
0b00000000,
0b00001100,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0xB2 ò
{
0b00000110,
0b00000000,
0b00001100,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0xB3 ó
{
0b00001110,
0b00000000,
0b00001100,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0xB4 ô
{
0b00001010,
0b00010100,
0b00000000,
0b00001100,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0xB5 õ
{
0b00001010,
0b00000000,
0b00001100,
0b00010010,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
}, // 0xB6 ö
{
0b00000000,
0b00000100,
0b00000000,
0b00011111,
0b00000000,
0b00000100,
0b00000000,
0b00000000,
}, // 0xB7 ÷
{
0b00000000,
0b00000000,
0b00000001,
0b00001110,
0b00010110,
0b00011010,
0b00011100,
0b00100000,
}, // 0xB8 ø
{
0b00011000,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00010110,
0b00001010,
0b00000000,
}, // 0xB9 ù
{
0b00000110,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00010110,
0b00001010,
0b00000000,
}, // 0xBA ú
{
0b00001110,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00010110,
0b00001010,
0b00000000,
}, // 0xBB û
{
0b00010010,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00010110,
0b00001010,
0b00000000,
}, // 0xBC ü
{
0b00000110,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00001110,
0b00000100,
0b00011000,
}, // 0xBD ý
{
0b00000000,
0b00011000,
0b00010000,
0b00011100,
0b00010010,
0b00011100,
0b00010000,
0b00011000,
}, // 0xBE þ
{
0b00001010,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00001110,
0b00000100,
0b00011000,
}, // 0xBF ÿ
};
/*
ISO/IEC 8859-1 (latin1)
0 1 2 3 4 5 6 7 8 9 A B C D E F
A NBSP ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ SHY ® ¯
B ° ± ² ³ ´ µ · ¸ ¹ º » ¼ ½ ¾ ¿
C À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï
D Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß
E à á â ã ä å æ ç è é ê ë ì í î ï
F ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ
*/
#endif // font_6x8_UTF8_C3_h

View File

@ -0,0 +1,986 @@
// 6x8 ascii font
#ifndef font_6x8_base_h
#define font_6x8_base_h
/**
* Momory size of basic ascii font: 768 bytes
*
*/
/*
0 1 2 3 4 5 6 7 8 9 A B C D E F
2 SP ! " # $ % & ' ( ) * + , - . /
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4 @ A B C D E F G H I J K L M N O
5 P Q R S T U V W X Y Z [ \ ] ^ _
6 ` a b c d e f g h i j k l m n o
7 p q r s t u v w x y z { | } ~
*/
const unsigned int font_char_width = 6;
const unsigned int font_char_height = 8;
const char font_20_7F[0x80-0x20][8] = {
{
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x20
{
0b00000100,
0b00001110,
0b00001110,
0b00000100,
0b00000100,
0b00000000,
0b00000100,
0b00000000,
}, // 0x21 !
{
0b00011011,
0b00011011,
0b00010010,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x22 "
{
0b00000000,
0b00001010,
0b00011111,
0b00001010,
0b00001010,
0b00011111,
0b00001010,
0b00000000,
}, // 0x23 #
{
0b00001000,
0b00001110,
0b00010000,
0b00001100,
0b00000010,
0b00011100,
0b00000100,
0b00000000,
}, // 0x24 $
{
0b00011001,
0b00011001,
0b00000010,
0b00000100,
0b00001000,
0b00010011,
0b00010011,
0b00000000,
}, // 0x25 %
{
0b00001000,
0b00010100,
0b00010100,
0b00001000,
0b00010101,
0b00010010,
0b00001101,
0b00000000,
}, // 0x26 &
{
0b00001100,
0b00001100,
0b00001000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x27 '
{
0b00000100,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00000100,
0b00000000,
}, // 0x28 (
{
0b00001000,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00001000,
0b00000000,
}, // 0x29 )
{
0b00000000,
0b00001010,
0b00001110,
0b00011111,
0b00001110,
0b00001010,
0b00000000,
0b00000000,
}, // 0x2A *
{
0b00000000,
0b00000100,
0b00000100,
0b00011111,
0b00000100,
0b00000100,
0b00000000,
0b00000000,
}, // 0x2B +
{
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00001100,
0b00001100,
0b00001000,
}, // 0x2C ,
{
0b00000000,
0b00000000,
0b00000000,
0b00011111,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x2D -
{
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00001100,
0b00001100,
0b00000000,
}, // 0x2E .
{
0b00000000,
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00000000,
0b00000000,
}, // 0x2F /
{
0b00001110,
0b00010001,
0b00010011,
0b00010101,
0b00011001,
0b00010001,
0b00001110,
0b00000000,
}, // 0x30 0
{
0b00000100,
0b00001100,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00001110,
0b00000000,
}, // 0x31 1
{
0b00001110,
0b00010001,
0b00000001,
0b00000110,
0b00001000,
0b00010000,
0b00011111,
0b00000000,
}, // 0x32 2
{
0b00001110,
0b00010001,
0b00000001,
0b00001110,
0b00000001,
0b00010001,
0b00001110,
0b00000000,
}, // 0x33 3
{
0b00000010,
0b00000110,
0b00001010,
0b00010010,
0b00011111,
0b00000010,
0b00000010,
0b00000000,
}, // 0x34 4
{
0b00011111,
0b00010000,
0b00010000,
0b00011110,
0b00000001,
0b00010001,
0b00001110,
0b00000000,
}, // 0x35 5
{
0b00000110,
0b00001000,
0b00010000,
0b00011110,
0b00010001,
0b00010001,
0b00001110,
0b00000000,
}, // 0x36 6
{
0b00011111,
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00001000,
0b00001000,
0b00000000,
}, // 0x37 7
{
0b00001110,
0b00010001,
0b00010001,
0b00001110,
0b00010001,
0b00010001,
0b00001110,
0b00000000,
}, // 0x38 8
{
0b00001110,
0b00010001,
0b00010001,
0b00001111,
0b00000001,
0b00000010,
0b00001100,
0b00000000,
}, // 0x39 9
{
0b00000000,
0b00000000,
0b00001100,
0b00001100,
0b00000000,
0b00001100,
0b00001100,
0b00000000,
}, // 0x3A :
{
0b00000000,
0b00000000,
0b00001100,
0b00001100,
0b00000000,
0b00001100,
0b00001100,
0b00001000,
}, // 0x3B ;
{
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000000,
}, // 0x3C <
{
0b00000000,
0b00000000,
0b00011111,
0b00000000,
0b00000000,
0b00011111,
0b00000000,
0b00000000,
}, // 0x3D =
{
0b00001000,
0b00000100,
0b00000010,
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00000000,
}, // 0x3E >
{
0b00001110,
0b00010001,
0b00000001,
0b00000110,
0b00000100,
0b00000000,
0b00000100,
0b00000000,
}, // 0x3F ?
{
0b00001110,
0b00010001,
0b00010111,
0b00010101,
0b00010111,
0b00010000,
0b00001110,
0b00000000,
}, // 0x40 @
{
0b00001110,
0b00010001,
0b00010001,
0b00010001,
0b00011111,
0b00010001,
0b00010001,
0b00000000,
}, // 0x41 A
{
0b00011110,
0b00010001,
0b00010001,
0b00011110,
0b00010001,
0b00010001,
0b00011110,
0b00000000,
}, // 0x42 B
{
0b00001110,
0b00010001,
0b00010000,
0b00010000,
0b00010000,
0b00010001,
0b00001110,
0b00000000,
}, // 0x43 C
{
0b00011110,
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00011110,
0b00000000,
}, // 0x44 D
{
0b00011111,
0b00010000,
0b00010000,
0b00011110,
0b00010000,
0b00010000,
0b00011111,
0b00000000,
}, // 0x45 E
{
0b00011111,
0b00010000,
0b00010000,
0b00011110,
0b00010000,
0b00010000,
0b00010000,
0b00000000,
}, // 0x46 F
{
0b00001110,
0b00010001,
0b00010000,
0b00010111,
0b00010001,
0b00010001,
0b00001111,
0b00000000,
}, // 0x47 G
{
0b00010001,
0b00010001,
0b00010001,
0b00011111,
0b00010001,
0b00010001,
0b00010001,
0b00000000,
}, // 0x48 H
{
0b00001110,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00001110,
0b00000000,
}, // 0x49 I
{
0b00000001,
0b00000001,
0b00000001,
0b00000001,
0b00010001,
0b00010001,
0b00001110,
0b00000000,
}, // 0x4A J
{
0b00010001,
0b00010010,
0b00010100,
0b00011000,
0b00010100,
0b00010010,
0b00010001,
0b00000000,
}, // 0x4B K
{
0b00010000,
0b00010000,
0b00010000,
0b00010000,
0b00010000,
0b00010000,
0b00011111,
0b00000000,
}, // 0x4C L
{
0b00010001,
0b00011011,
0b00010101,
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00000000,
}, // 0x4D M
{
0b00010001,
0b00011001,
0b00010101,
0b00010011,
0b00010001,
0b00010001,
0b00010001,
0b00000000,
}, // 0x4E N
{
0b00001110,
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00001110,
0b00000000,
}, // 0x4F O
{
0b00011110,
0b00010001,
0b00010001,
0b00011110,
0b00010000,
0b00010000,
0b00010000,
0b00000000,
}, // 0x50 P
{
0b00001110,
0b00010001,
0b00010001,
0b00010001,
0b00010101,
0b00010010,
0b00001101,
0b00000000,
}, // 0x51 Q
{
0b00011110,
0b00010001,
0b00010001,
0b00011110,
0b00010010,
0b00010001,
0b00010001,
0b00000000,
}, // 0x52 R
{
0b00001110,
0b00010001,
0b00010000,
0b00001110,
0b00000001,
0b00010001,
0b00001110,
0b00000000,
}, // 0x53 S
{
0b00011111,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000000,
}, // 0x54 T
{
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00001110,
0b00000000,
}, // 0x55 U
{
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00001010,
0b00000100,
0b00000000,
}, // 0x56 V
{
0b00010001,
0b00010001,
0b00010101,
0b00010101,
0b00010101,
0b00010101,
0b00001010,
0b00000000,
}, // 0x57 W
{
0b00010001,
0b00010001,
0b00001010,
0b00000100,
0b00001010,
0b00010001,
0b00010001,
0b00000000,
}, // 0x58 X
{
0b00010001,
0b00010001,
0b00010001,
0b00001010,
0b00000100,
0b00000100,
0b00000100,
0b00000000,
}, // 0x59 Y
{
0b00011110,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00010000,
0b00011110,
0b00000000,
}, // 0x5A Z
{
0b00001110,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00001110,
0b00000000,
}, // 0x5B [
{
0b00000000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
0b00000000,
0b00000000,
}, // 0x5C backslash
{
0b00001110,
0b00000010,
0b00000010,
0b00000010,
0b00000010,
0b00000010,
0b00001110,
0b00000000,
}, // 0x5D ]
{
0b00000100,
0b00001010,
0b00010001,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x5E ^
{
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00111111,
}, // 0x5F _
{
0b00001100,
0b00001100,
0b00000100,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x60 `
{
0b00000000,
0b00000000,
0b00001110,
0b00000001,
0b00001111,
0b00010001,
0b00001111,
0b00000000,
}, // 0x61 a
{
0b00010000,
0b00010000,
0b00011110,
0b00010001,
0b00010001,
0b00010001,
0b00011110,
0b00000000,
}, // 0x62 b
{
0b00000000,
0b00000000,
0b00001110,
0b00010001,
0b00010000,
0b00010001,
0b00001110,
0b00000000,
}, // 0x63 c
{
0b00000001,
0b00000001,
0b00001111,
0b00010001,
0b00010001,
0b00010001,
0b00001111,
0b00000000,
}, // 0x64 d
{
0b00000000,
0b00000000,
0b00001110,
0b00010001,
0b00011110,
0b00010000,
0b00001110,
0b00000000,
}, // 0x65 e
{
0b00000110,
0b00001000,
0b00001000,
0b00011110,
0b00001000,
0b00001000,
0b00001000,
0b00000000,
}, // 0x66 f
{
0b00000000,
0b00000000,
0b00001111,
0b00010001,
0b00010001,
0b00001111,
0b00000001,
0b00001110,
}, // 0x67 g
{
0b00010000,
0b00010000,
0b00011100,
0b00010010,
0b00010010,
0b00010010,
0b00010010,
0b00000000,
}, // 0x68 h
{
0b00000100,
0b00000000,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000110,
0b00000000,
}, // 0x69 i
{
0b00000010,
0b00000000,
0b00000110,
0b00000010,
0b00000010,
0b00000010,
0b00010010,
0b00001100,
}, // 0x6A j
{
0b00010000,
0b00010000,
0b00010010,
0b00010100,
0b00011000,
0b00010100,
0b00010010,
0b00000000,
}, // 0x6B k
{
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000110,
0b00000000,
}, // 0x6C l
{
0b00000000,
0b00000000,
0b00011010,
0b00010101,
0b00010101,
0b00010001,
0b00010001,
0b00000000,
}, // 0x6D m
{
0b00000000,
0b00000000,
0b00011100,
0b00010010,
0b00010010,
0b00010010,
0b00010010,
0b00000000,
}, // 0x6E n
{
0b00000000,
0b00000000,
0b00001110,
0b00010001,
0b00010001,
0b00010001,
0b00001110,
0b00000000,
}, // 0x6F o
{
0b00000000,
0b00000000,
0b00011110,
0b00010001,
0b00010001,
0b00010001,
0b00011110,
0b00010000,
}, // 0x70 p
{
0b00000000,
0b00000000,
0b00001111,
0b00010001,
0b00010001,
0b00010001,
0b00001111,
0b00000001,
}, // 0x71 q
{
0b00000000,
0b00000000,
0b00010110,
0b00001001,
0b00001000,
0b00001000,
0b00011100,
0b00000000,
}, // 0x72 r
{
0b00000000,
0b00000000,
0b00001110,
0b00010000,
0b00001110,
0b00000001,
0b00001110,
0b00000000,
}, // 0x73 s
{
0b00000000,
0b00001000,
0b00011110,
0b00001000,
0b00001000,
0b00001010,
0b00000100,
0b00000000,
}, // 0x74 t
{
0b00000000,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00010110,
0b00001010,
0b00000000,
}, // 0x75 u
{
0b00000000,
0b00000000,
0b00010001,
0b00010001,
0b00010001,
0b00001010,
0b00000100,
0b00000000,
}, // 0x76 v
{
0b00000000,
0b00000000,
0b00010001,
0b00010001,
0b00010101,
0b00011111,
0b00001010,
0b00000000,
}, // 0x77 w
{
0b00000000,
0b00000000,
0b00010010,
0b00010010,
0b00001100,
0b00010010,
0b00010010,
0b00000000,
}, // 0x78 x
{
0b00000000,
0b00000000,
0b00010010,
0b00010010,
0b00010010,
0b00001110,
0b00000100,
0b00011000,
}, // 0x79 y
{
0b00000000,
0b00000000,
0b00011110,
0b00000010,
0b00001100,
0b00010000,
0b00011110,
0b00000000,
}, // 0x7A z
{
0b00000110,
0b00001000,
0b00001000,
0b00011000,
0b00001000,
0b00001000,
0b00000110,
0b00000000,
}, // 0x7B {
{
0b00000100,
0b00000100,
0b00000100,
0b00000000,
0b00000100,
0b00000100,
0b00000100,
0b00000000,
}, // 0x7C |
{
0b00001100,
0b00000010,
0b00000010,
0b00000011,
0b00000010,
0b00000010,
0b00001100,
0b00000000,
}, // 0x7D }
{
0b00001010,
0b00010100,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
}, // 0x7E ~
{
0b00000100,
0b00001110,
0b00011011,
0b00010001,
0b00010001,
0b00011111,
0b00000000,
0b00000000,
}, // 0x7F ␡
};
#endif // font_6x8_base_h

View File

@ -4,8 +4,8 @@
"description": "Forked version of Arduino HttpClient to support BearSSL instead of mbedTLS",
"license": "MIT",
"homepage": "https://github.com/arendst/Tasmota",
"frameworks": "*",
"platforms": "*",
"frameworks": "arduino",
"platforms": "espressif32",
"authors":
{
"name": "Stephan Hadinger",

View File

@ -4,8 +4,8 @@
"description": "Simple filesystem to open an uncompressed ZIP file and read-only",
"license": "MIT",
"homepage": "https://github.com/arendst/Tasmota",
"frameworks": "*",
"platforms": "*",
"frameworks": "arduino",
"platforms": "espressif32",
"authors":
{
"name": "Stephan Hadinger",

View File

@ -157,9 +157,7 @@ extern void be_load_driver_audio_lib(bvm *vm);
#endif
#ifdef USE_LVGL
extern void be_load_lv_color_class(bvm *vm);
extern void be_load_lv_font_class(bvm *vm);
extern void be_load_LVGL_glob_class(bvm *vm);
#include "lv_berry.h"
// custom widgets
extern void be_load_lv_signal_bars_class(bvm *vm);
extern void be_load_lv_wifi_bars_class(bvm *vm);
@ -213,10 +211,7 @@ BERRY_API void be_load_custom_libs(bvm *vm)
#endif
#ifdef USE_LVGL
// LVGL
be_load_lv_color_class(vm);
be_load_lv_font_class(vm);
be_load_LVGL_glob_class(vm);
be_load_lvgl_classes(vm);
// custom widgets
be_load_lv_signal_bars_class(vm);
be_load_lv_wifi_bars_class(vm);

View File

@ -1,2 +1,2 @@
#!/bin/bash
python3 tools/pycoc/main.py -o generate src default ../berry_mapping/src -c default/berry_conf.h
python3 tools/pycoc/main.py -o generate src default ../berry_mapping/src ../../libesp32_lvgl/lv_berry/src -c default/berry_conf.h

View File

@ -206,6 +206,7 @@ extern const bcstring be_const_str_add;
extern const bcstring be_const_str_add_anim;
extern const bcstring be_const_str_add_cmd;
extern const bcstring be_const_str_add_driver;
extern const bcstring be_const_str_add_handler;
extern const bcstring be_const_str_add_header;
extern const bcstring be_const_str_add_rule;
extern const bcstring be_const_str_addr;
@ -464,6 +465,7 @@ extern const bcstring be_const_str_length_X20in_X20bits_X20must_X20be_X20between
extern const bcstring be_const_str_light;
extern const bcstring be_const_str_line_dsc;
extern const bcstring be_const_str_list;
extern const bcstring be_const_str_list_handlers;
extern const bcstring be_const_str_listdir;
extern const bcstring be_const_str_load;
extern const bcstring be_const_str_load_templates;
@ -473,11 +475,13 @@ extern const bcstring be_const_str_log10;
extern const bcstring be_const_str_loop;
extern const bcstring be_const_str_lower;
extern const bcstring be_const_str_lv;
extern const bcstring be_const_str_lv_;
extern const bcstring be_const_str_lv_event;
extern const bcstring be_const_str_lv_event_cb;
extern const bcstring be_const_str_lv_obj;
extern const bcstring be_const_str_lv_obj_class;
extern const bcstring be_const_str_lvgl_event_dispatch;
extern const bcstring be_const_str_make_cb;
extern const bcstring be_const_str_map;
extern const bcstring be_const_str_math;
extern const bcstring be_const_str_matrix;

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,16 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libcb_map) {
{ be_const_key(make_cb, -1), be_const_func(be_cb_make_cb) },
{ be_const_key(list_handlers, 3), be_const_func(be_cb_list_handlers) },
{ be_const_key(get_cb_list, -1), be_const_func(be_cb_get_cb_list) },
{ be_const_key(gen_cb, -1), be_const_func(be_cb_gen_cb) },
{ be_const_key(add_handler, -1), be_const_func(be_cb_add_handler) },
};
static be_define_const_map(
m_libcb_map,
2
5
);
static be_define_const_module(

View File

@ -1,40 +0,0 @@
/********************************************************************
* Tasmota LVGL Headers
*******************************************************************/
#ifndef __BE_LVGL_H__
#define __BE_LVGL_H__
#include "be_constobj.h"
#ifdef USE_LVGL
#include "lvgl.h"
#ifdef __cplusplus
extern "C" {
#endif
// table of functions per class
typedef struct lvbe_call_c_t {
const char * name;
void * func;
const char * return_type;
const char * arg_type;
} lvbe_call_c_t;
// list of classes and function tables
typedef struct lvbe_call_c_classes_t {
const char * name;
const bclass * cl;
const lvbe_call_c_t * func_table;
size_t size;
} lvbe_call_c_classes_t;
extern const lvbe_call_c_classes_t lv_classes[];
extern const size_t lv_classes_size;
#ifdef __cplusplus
}
#endif
#endif // USE_LVGL
#endif // __BE_LVGL_H__

View File

@ -14,8 +14,8 @@
},
"version": "7.0",
"license": "MIT License",
"frameworks": "*",
"platforms": "*",
"frameworks": "arduino",
"platforms": "espressif32",
"build": {
"srcFilter": [
"+<*.c>",

View File

@ -4,8 +4,8 @@
"description": "Mapping to C functions",
"license": "MIT",
"homepage": "https://github.com/arendst/Tasmota",
"frameworks": "*",
"platforms": "*",
"frameworks": "arduino",
"platforms": "espressif32",
"authors":
{
"name": "Stephan Hadinger",

View File

@ -10,6 +10,7 @@
#include "be_gc.h"
#include "be_exec.h"
#include "be_vm.h"
#include "be_mem.h"
/*********************************************************************************************\
* Callback structures
@ -69,11 +70,115 @@ static const berry_callback_t berry_callback_array[BE_MAX_CB] = {
typedef struct be_callback_hook {
bvm *vm;
bgcobject *f;
bvalue f;
} be_callback_hook;
typedef struct be_callback_handler_list_t {
bvm *vm;
bvalue f;
struct be_callback_handler_list_t *next;
} be_callback_handler_list_t;
static be_callback_hook be_cb_hooks[BE_MAX_CB] = {0};
static int32_t be_cb_gen_cb(bvm *vm);
static be_callback_handler_list_t be_callback_default_gen_cb = {
NULL,
be_const_func(&be_cb_gen_cb),
NULL
};
static be_callback_handler_list_t *be_callback_handler_list_head = &be_callback_default_gen_cb; /* linked list of handlers */
/*********************************************************************************************\
* `add_handler`: Add an external handler to `make_cb()`
*
* This is typically used by LVGL mapping to handle widget callbacks, the handler
* needs to record additional infomation to disambiguate the call
*
* arg1: function (or closure)
\*********************************************************************************************/
static int32_t be_cb_add_handler(bvm *vm) {
int32_t top = be_top(vm);
if (top >= 1 && be_isfunction(vm, 1)) {
bvalue *v = be_indexof(vm, 1);
be_callback_handler_list_t *elt = be_os_malloc(sizeof(be_callback_handler_list_t));
if (!elt) { be_throw(vm, BE_MALLOC_FAIL); }
if (be_isgcobj(v)) {
be_gc_fix_set(vm, v->v.gc, btrue); // mark the function as non-gc
}
elt->vm = vm;
elt->f = *v;
elt->next = be_callback_handler_list_head; /* insert as new head */
be_callback_handler_list_head = elt;
be_return_nil(vm);
}
be_raise(vm, "value_error", "arg must be a function");
}
/*********************************************************************************************\
* `list_handlers`: List all cb handlers registered for this VM
*
* Used for debugging only
*
* No args
\*********************************************************************************************/
static int32_t be_cb_list_handlers(bvm *vm) {
be_newobject(vm, "list");
for (be_callback_handler_list_t *elt = be_callback_handler_list_head; elt != NULL; elt = elt->next) {
if (elt->vm == vm) { /* on purpose don't show the default handler, just pretend it's not there since it's default */
bvalue *top = be_incrtop(vm);
*top = elt->f;
be_data_push(vm, -2);
be_pop(vm, 1);
}
}
be_pop(vm, 1);
be_return(vm);
}
/*********************************************************************************************\
* `make_cb`: high-level call for creating a callback.
*
* This function is called by `be_mapping` when generating a callback with a type name.
* LVGL typically needs to register typed callbacks
*
* arg1: function (or closure)
* arg2: type name for callback (optional)
* argN: any other callback specific arguments (unlimited number, passed as-is)
\*********************************************************************************************/
static int32_t be_cb_make_cb(bvm *vm) {
int32_t argc = be_top(vm);
if (argc >= 1 && be_isfunction(vm, 1)) {
bvalue *v = be_indexof(vm, 1);
for (be_callback_handler_list_t *elt = be_callback_handler_list_head; elt != NULL; elt = elt->next) {
if (elt->vm == vm || elt->vm == NULL) { // if elt->vm is NULL then we accept any VM
// call the handler and check result
bvalue *top = be_incrtop(vm);
*top = elt->f;
// var_setobj(top, elt->f->type, elt->f); // push function - arg0
for (int i=1; i<=argc; i++) { // push all arguments including function
be_pushvalue(vm, i);
}
be_call(vm, argc); // call handler
be_pop(vm, argc); // remove arguments, top of stack has the result
// if top of stack is `comptr` then it is successful
if (be_iscomptr(vm, -1)) {
be_return(vm);
} else {
be_pop(vm, 1); // remove top, rinse and repeat
}
}
}
// if we are here, it means that no handler has handled the request
}
be_raise(vm, "value_error", "arg must be a function");
}
/*********************************************************************************************\
* `gen_cb`: Generate a new callback
*
@ -85,17 +190,16 @@ static int32_t be_cb_gen_cb(bvm *vm) {
// find first available slot
int32_t slot;
for (slot = 0; slot < BE_MAX_CB; slot++) {
if (be_cb_hooks[slot].f == NULL) break;
if (be_cb_hooks[slot].f.type == BE_NIL) break;
}
bvalue *v = be_indexof(vm, 1);
if (slot < BE_MAX_CB) {
// found a free slot
bgcobject * f = v->v.gc;
// mark the function as non-gc
be_gc_fix_set(vm, f, btrue);
if (be_isgcobj(v)) {
be_gc_fix_set(vm, v->v.gc, btrue); // mark the function as non-gc
}
// record pointers
be_cb_hooks[slot].vm = vm;
be_cb_hooks[slot].f = f;
be_cb_hooks[slot].f = *v;
be_pushcomptr(vm, (void*) berry_callback_array[slot]);
be_return(vm);
} else {
@ -115,7 +219,9 @@ static int32_t be_cb_get_cb_list(bvm *vm) {
for (uint32_t i=0; i < BE_MAX_CB; i++) {
if (be_cb_hooks[i].vm) {
if (vm == be_cb_hooks[i].vm) { // make sure it corresponds to this vm
be_pushcomptr(vm, be_cb_hooks[i].f);
bvalue *top = be_incrtop(vm);
*top = be_cb_hooks[i].f;
// be_pushcomptr(vm, be_cb_hooks[i].f);
be_data_push(vm, -2);
be_pop(vm, 1);
}
@ -140,11 +246,11 @@ static int32_t call_berry_cb(int32_t num, int32_t v0, int32_t v1, int32_t v2, in
if (num < 0 || num >= BE_MAX_CB || be_cb_hooks[num].vm == NULL) return 0; // invalid call, avoid a crash
bvm * vm = be_cb_hooks[num].vm;
bgcobject * f = be_cb_hooks[num].f;
bvalue *f = &be_cb_hooks[num].f;
// push function (don't check type)
bvalue *top = be_incrtop(vm);
var_setobj(top, f->type, f);
*top = *f;
// push args
be_pushint(vm, v0);
be_pushint(vm, v1);
@ -166,6 +272,10 @@ static int32_t call_berry_cb(int32_t num, int32_t v0, int32_t v1, int32_t v2, in
module cb (scope: global) {
gen_cb, func(be_cb_gen_cb)
get_cb_list, func(be_cb_get_cb_list)
add_handler, func(be_cb_add_handler)
list_handlers, func(be_cb_list_handlers)
make_cb, func(be_cb_make_cb)
}
@const_object_info_end */
#include "../../berry/generate/be_fixed_cb.h"

View File

@ -0,0 +1,453 @@
/*********************************************************************************************\
* Class wrappers for native objects
*
* These class are simple wrappers (containers) for a pointer of an external object.
* The pointer is stored interanlly by the class.
*
* The constructor of this class must accept the first argument to be `comptr`,
* in such case, the constructor must store the pointer.
* The class is not supposed to free the object at `deinit` time.
\*********************************************************************************************/
#include "be_mapping.h"
#include "be_exec.h"
#include <string.h>
// By default the cb generator is cb.gen_cb
// This can be changed. Note: it is across all VMs
static const char * be_gen_cb_name = "cb.gen_cb";
void be_set_gen_cb_name(bvm *vm, const char * gen_cb) {
if (gen_cb) be_gen_cb_name = gen_cb;
}
/*********************************************************************************************\
* Converision from real <-> int
*
* Warning, works only if sizeof(intptr_t) == sizeof(breal)
* On ESP32, int=32bits, real=float (32bits)
\*********************************************************************************************/
static intptr_t realasint(breal v) {
intptr_t i;
i = *((intptr_t*) &v);
return i;
}
static breal intasreal(intptr_t v) {
breal r;
r = *((breal*) &v);
return r;
}
/*********************************************************************************************\
* Create an object of `class_name` given an external poinrt `ptr`.
*
* Instanciates the class and calls `init()` with `ptr` wrapped in `comptr` as single arg.
* Both arguments but nost bu NULL.
*
* On return, the created instance is top of stack.
\*********************************************************************************************/
void be_create_class_wrapper(bvm *vm, const char * class_name, void * ptr) {
if (ptr == NULL) {
be_throw(vm, BE_MALLOC_FAIL);
}
be_getglobal(vm, class_name); // stack = class
be_call(vm, 0); // instanciate, stack = instance
be_getmember(vm, -1, "init"); // stack = instance, init_func
be_pushvalue(vm, -2); // stack = instance, init_func, instance
be_pushcomptr(vm, ptr); // stack = instance, init_func, instance, ptr
be_call(vm, 2); // stack = instance, ret, instance, ptr
be_pop(vm, 3); // stack = instance
}
/*********************************************************************************************\
* Find an object by global or composite name.
*
* I.e. `lv.lv_object` will check for a global called `lv` and a member `lv_object`
*
* Only supports one level of depth, meaning a class within a module.
* Does not check the type of the object found.
*
* Arguments:
* `name`: can be NULL, in such case considers the member as not found
*
* Case 1: (no dot in name) `lv_wifi_bars` will look for a global variable `lv_wifi_bars`
* Case 2: (dot in name) `lvgl.lv_obj` will get global `lvgl` and look for `lv_obj` within this module
*
* Returns the number of elements pushed on the stack: 1 for module, 2 for instance method, 0 if not found
\*********************************************************************************************/
int be_find_global_or_module_member(bvm *vm, const char * name) {
char *saveptr;
if (name == NULL) {
be_pushnil(vm);
return 0;
}
char name_buf[strlen(name)+1];
strcpy(name_buf, name);
char * prefix = strtok_r(name_buf, ".", &saveptr);
char * suffix = strtok_r(NULL, ".", &saveptr);
if (suffix) {
if (!be_getglobal(vm, prefix)) {
// global not found, try module
be_pop(vm, 1);
if (!be_getmodule(vm, prefix)) {
return 0;
}
}
if (!be_isnil(vm, -1)) {
if (be_getmember(vm, -1, suffix)) {
if (be_isinstance(vm, -2)) { // instance, so we need to push method + instance
be_pushvalue(vm, -2);
be_remove(vm, -3);
return 2;
} else { // not instane, so keep only the top object
be_remove(vm, -2);
return 1;
}
} else {
be_pop(vm, 2);
return 0;
}
}
be_pop(vm, 1); // remove nil
return 0;
} else { // no suffix, get the global object
if (be_getglobal(vm, prefix)) {
return 1;
}
be_pop(vm, 1);
return 0;
}
}
/*********************************************************************************************\
* Automatically parse Berry stack and call the C function accordingly
*
* This function takes the n incoming arguments and pushes them as arguments
* on the stack for the C function:
* - be_int -> int32_t
* - be_bool -> int32_t with value 0/1
* - be_string -> const char *
* - be_instance -> gets the member "_p" and pushes as void*
*
* This works because C silently ignores any unwanted arguments.
* There is a strong requirements that all ints and pointers are 32 bits.
* Float is not supported but could be added. Double cannot be supported because they are 64 bits
*
* Optional argument:
* - return_type: the C function return value is int32_t and is converted to the
* relevant Berry object depending on this char:
* '' (default): nil, no value
* 'i' be_int
* 'b' be_bool
* 's' be_str
*
* - arg_type: optionally check the types of input arguments, or throw an error
* string of argument types, '[' indicates that the following parameters are optional
* '.' don't care
* 'i' be_int
* 'b' be_bool
* 's' be_string
* 'c' C callback
* '-' ignore and don't send to C function
* 'lv_obj' be_instance of type or subtype
* '^lv_event_cb' callback of a named class - will call `_lvgl.gen_cb(arg_type, closure, self)` and expects a callback address in return
*
* Ex: ".ii" takes 3 arguments, first one is any type, followed by 2 ints
\*********************************************************************************************/
// general form of lv_obj_t* function, up to 4 parameters
// We can only send 32 bits arguments (no 64 bits nor double) and we expect pointers to be 32 bits
// read a single value at stack position idx, convert to int.
// if object instance, get `_p` member and convert it recursively
intptr_t be_convert_single_elt(bvm *vm, int idx, const char * arg_type, const char * gen_cb) {
// berry_log_C("be_convert_single_elt(idx=%i, argtype='%s', gen_cb=%p, type=%s", idx, arg_type ? arg_type : "", gen_cb ? gen_cb : "", be_typename(vm, idx));
int ret = 0;
char provided_type = 0;
idx = be_absindex(vm, idx); // make sure we have an absolute index
// berry_log_C(">> 0 idx=%i arg_type=%s", idx, arg_type ? arg_type : "NULL");
if (arg_type == NULL) { arg_type = "."; } // if no type provided, replace with wildchar
size_t arg_type_len = strlen(arg_type);
// handle callbacks first, since a wrong parameter will always yield to a crash
if (arg_type_len > 1 && arg_type[0] == '^') { // it is a callback
arg_type++; // skip first character
if (be_isclosure(vm, idx)) {
ret = be_find_global_or_module_member(vm, gen_cb);
if (ret) {
be_pushvalue(vm, idx);
be_pushvalue(vm, 1);
be_pushstring(vm, arg_type);
be_call(vm, 2 + ret);
const void * func = be_tocomptr(vm, -(3 + ret));
be_pop(vm, 3 + ret);
// berry_log_C("func=%p", func);
return (int32_t) func;
} else {
be_raisef(vm, "type_error", "Can't find callback generator: %s", gen_cb);
}
} else {
be_raise(vm, "type_error", "Closure expected for callback type");
}
}
// first convert the value to int32
if (be_isint(vm, idx)) {
if (arg_type[0] == 'f') {
ret = realasint((float)be_toint(vm, idx)); provided_type = 'f';
} else {
ret = be_toint(vm, idx); provided_type = 'i'; }
}
else if (be_isbool(vm, idx)) { ret = be_tobool(vm, idx); provided_type = 'b'; }
else if (be_isstring(vm, idx)) { ret = (intptr_t) be_tostring(vm, idx); provided_type = 's'; }
else if (be_iscomptr(vm, idx)) { ret = (intptr_t) be_tocomptr(vm, idx); provided_type = 'c'; }
else if (be_isnil(vm, idx)) { ret = 0; provided_type = 'c'; }
else if (be_isreal(vm, idx)) { ret = realasint(be_toreal(vm, idx)); provided_type = 'f'; }
// check if simple type was a match
if (provided_type) {
bbool type_ok = bfalse;
type_ok = (arg_type[0] == '.'); // any type is accepted
type_ok = type_ok || (arg_type[0] == provided_type); // or type is a match
type_ok = type_ok || (ret == 0 && arg_type_len != 1); // or NULL is accepted for an instance
if (!type_ok) {
be_raisef(vm, "type_error", "Unexpected argument type '%c', expected '%s'", provided_type, arg_type);
}
// berry_log_C("be_convert_single_elt provided type=%i", ret);
return ret;
}
// non-simple type
if (be_isinstance(vm, idx)) {
// check if the instance is a subclass of `bytes()``
be_getbuiltin(vm, "bytes");
if (be_isderived(vm, idx)) {
be_pop(vm, 1);
be_getmember(vm, idx, "_buffer");
be_pushvalue(vm, idx);
be_call(vm, 1);
int32_t ret = (int32_t) be_tocomptr(vm, -2);
be_pop(vm, 2);
return ret;
} else {
be_pop(vm, 1);
// we accept either `_p` or `.p` attribute to retrieve a pointer
if (!be_getmember(vm, idx, "_p")) {
be_pop(vm, 1); // remove `nil`
be_getmember(vm, idx, ".p");
}
int32_t ret = be_convert_single_elt(vm, -1, NULL, NULL); // recurse
be_pop(vm, 1);
if (arg_type_len > 1) {
// Check type
be_classof(vm, idx);
int class_found = be_find_global_or_module_member(vm, arg_type);
// Stack: class_of_idx, class_of_target (or nil)
if (class_found) {
if (!be_isderived(vm, -2)) {
be_raisef(vm, "type_error", "Unexpected class type '%s', expected '%s'", be_classname(vm, idx), arg_type);
}
} else {
be_raisef(vm, "value_error", "Unable to find class '%s' (%d)", arg_type, arg_type_len);
}
be_pop(vm, 2);
} else if (arg_type[0] != '.') {
be_raisef(vm, "value_error", "Unexpected instance type '%s', expected '%s'", be_classname(vm, idx), arg_type);
}
return ret;
}
} else {
be_raisef(vm, "value_error", "Unexpected '%s'", be_typename(vm, idx));
}
return ret;
}
/*********************************************************************************************\
* Calling any LVGL function with auto-mapping
*
\*********************************************************************************************/
// check input parameters, and create callbacks if needed
// change values in place
//
// Format:
// - either a lowercase character encoding for a simple type
// - 'b': bool
// - 'i': int (int32_t)
// - 's': string (const char *)
//
// - a class name surroungded by parenthesis
// - '(lv_button)' -> lv_button class or derived
// - '[lv_event_cb]' -> callback type, still prefixed with '^' to mark that it is cb
//
void be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, intptr_t p[8]) {
bbool arg_type_check = (arg_type != NULL); // is type checking activated
int32_t arg_idx = 0; // position in arg_type string
bbool arg_optional = bfalse; // are remaining types optional?
char type_short_name[32];
uint32_t p_idx = 0; // index in p[], is incremented with each parameter except '-'
for (uint32_t i = 0; i < argc; i++) {
type_short_name[0] = 0; // clear string
// extract individual type
if (NULL != arg_type) {
if (arg_type[arg_idx] == '[' || arg_type[arg_idx] == ']') { // '[' is a marker that following parameters are optional and default to NULL
arg_optional = btrue;
arg_idx++;
}
switch (arg_type[arg_idx]) {
case '-':
arg_idx++;
continue; // ignore current parameter and advance
case '.':
case 'a'...'z':
type_short_name[0] = arg_type[arg_idx];
type_short_name[1] = 0;
arg_idx++;
break;
case '(':
case '^':
{
uint32_t prefix = 0;
if (arg_type[arg_idx] == '^') {
type_short_name[0] = '^';
type_short_name[1] = 0;
prefix = 1;
}
uint32_t offset = 0;
arg_idx++;
while (arg_type[arg_idx + offset] != ')' && arg_type[arg_idx + offset] != '^' && arg_type[arg_idx + offset] != 0 && offset+prefix+1 < sizeof(type_short_name)) {
type_short_name[offset+prefix] = arg_type[arg_idx + offset];
type_short_name[offset+prefix+1] = 0;
offset++;
}
if (arg_type[arg_idx + offset] == 0) {
arg_type = NULL; // no more parameters, stop iterations
}
arg_idx += offset + 1;
}
break;
case 0:
arg_type = NULL; // stop iterations
break;
}
}
// AddLog(LOG_LEVEL_INFO, ">> be_call_c_func arg %i, type %s", i, arg_type_check ? type_short_name : "<null>");
p[p_idx] = be_convert_single_elt(vm, i + arg_start, arg_type_check ? type_short_name : NULL, "cb.make_cb");
// berry_log_C("< ret[%i]=%i", p_idx, p[p_idx]);
p_idx++;
}
// check if we are missing arguments
if (!arg_optional && arg_type != NULL && arg_type[arg_idx] != 0) {
be_raisef(vm, "value_error", "Missing arguments, remaining type '%s'", &arg_type[arg_idx]);
}
}
//
// Internal function
//
// Called for constructors, i.e. C function mapped to Berry `init()`
//
// Pre-conditions:
// The instance must be at stack position `1` (default when calling `init()`)
//
// Arguments:
// vm: point to Berry vm (as usual)
// ptr: the C pointer for internal data (can be NULL), will be stored in an instance variable
// name: name of instance variable to store the pointer as `comptr`.
// If NULL, this function does nothing
// the name can be prefixed with `+` or `=`, if so first char is ignored.
// Ex: `+_p` stores in instance variable `_p`
// `+` forbids any NULL value (raises an exception) while `=` allows a NULL value
static void be_set_ctor_ptr(bvm *vm, void * ptr, const char *name) {
if (name == NULL) return; // do nothing if no name of attribute
if (name[0] == '+' && ptr == NULL) { be_raise(vm, "value_error", "argument cannot be NULL"); }
if (name[0] == '+' || name[0] == '=') { name++; } // skip prefix '^' if any
if (strlen(name) == 0) return; // do nothing if name is empty
be_pushcomptr(vm, ptr);
if (be_setmember(vm, 1, name)) {
be_pop(vm, 1);
} else {
be_raisef(vm, "attribute_error", "Missing member '%s' in ctor", name);
}
}
/*********************************************************************************************\
* Call a C function with auto-mapping
*
* Arguments:
* vm: pointer to Berry vm (as ususal)
* func: pointer to C function
* return_type: how to convert the result into a Berry type
* arg_type: string describing the optional and mandatory parameters
*
* Note: the C function mapping supports max 8 arguments and does not directly support
* pointers to values (although it is possible to mimick with classes)
\*********************************************************************************************/
int be_call_c_func(bvm *vm, void * func, const char * return_type, const char * arg_type) {
intptr_t p[8] = {0,0,0,0,0,0,0,0};
int argc = be_top(vm); // Get the number of arguments
// the following describe the active payload for the C function (start and count)
// this is because the `init()` constructor first arg is not passed to the C function
int arg_start = 1; // start with standard values
int arg_count = argc;
// check if we call a constructor, in this case we store the return type into the new object
// check if we call a constructor with a comptr as first arg
if (return_type && (return_type[0] == '+' || return_type[0] == '=')) {
if (argc > 1 && be_iscomptr(vm, 2)) {
void * obj = be_tocomptr(vm, 2);
be_set_ctor_ptr(vm, obj, return_type);
be_return_nil(vm);
} else {
// we need to discard the first arg
arg_start++;
arg_count--;
}
}
fn_any_callable f = (fn_any_callable) func;
be_check_arg_type(vm, arg_start, arg_count, arg_type, p);
intptr_t ret = 0;
if (f) ret = (*f)(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
// berry_log_C("be_call_c_func '%s' -> '%s': (%i,%i,%i,%i,%i,%i) -> %i", return_type, arg_type, p[0], p[1], p[2], p[3], p[4], p[5], ret);
if ((return_type == NULL) || (strlen(return_type) == 0)) { be_return_nil(vm); } // does not return
else if (return_type[0] == '+' || return_type[0] == '=') {
void * obj = (void*) ret;
be_set_ctor_ptr(vm, obj, return_type);
be_return_nil(vm);
}
else if (strlen(return_type) == 1) {
switch (return_type[0]) {
case '.': // fallback next
case 'i': be_pushint(vm, ret); break;
case 'b': be_pushbool(vm, ret); break;
case 's': be_pushstring(vm, (const char*) ret); break;
case 'c': be_pushint(vm, ret); break; // TODO missing 'c' general callback type
default: be_raise(vm, "internal_error", "Unsupported return type"); break;
}
be_return(vm);
} else { // class name
be_find_global_or_module_member(vm, return_type);
be_pushcomptr(vm, (void*) ret); // stack = class, ptr
be_pushcomptr(vm, (void*) -1); // stack = class, ptr, -1
be_call(vm, 2); // instanciate with 2 arguments, stack = instance, -1, ptr
be_pop(vm, 2); // stack = instance
be_return(vm);
}
}

View File

@ -0,0 +1,64 @@
/*********************************************************************************************\
* Add const virtual members to classes and modules from C static tables
*
* This allows to creates hundreds of constant members (integers, strings...)
* stored in a C array instead of explicit berry members.
*
* It has the following advantages:
* - consumes much less flash memory, especially with hundreds of members
* - allows C preprocessor to compute the value at compile time (instead of pure numerical numbers)
* - allows to compute pointer addresses to C structures
*
* Takes a pointer to be_const_member_t array and size
* Returns true if a match was found. In such case the result is on Berry stack
*
* Encoding depend on prefix (which is skipped when matching names):
* 1. `COLOR_WHITE` int value
* 3. `$SYMBOL_OK"` string pointer
* 4. `&seg7_font` comptr
\*********************************************************************************************/
#include "be_mapping.h"
#include "be_exec.h"
#include <string.h>
/*********************************************************************************************\
* Takes a pointer to be_const_member_t array and size
* Returns true if a match was found. In such case the result is on Berry stack
*
* Can be called directly by `member()` function, takes the name of the member from
* berry stack at position 1.
*
* Encoding depend on prefix (which is skipped when matching names):
* 1. `COLOR_WHITE` int value
* 3. `$SYMBOL_OK"` string pointer
* 4. `&seg7_font` comptr
*
* The array must be lexically sorted, but the sort function must ignore the prefix `$` or `&`
\*********************************************************************************************/
bbool be_const_member(bvm *vm, const be_const_member_t * definitions, size_t def_len) {
int32_t argc = be_top(vm); // Get the number of arguments
if (argc == 1 && be_isstring(vm, 1)) {
const char * needle = be_tostring(vm, 1);
int32_t idx;
idx = be_map_bin_search(needle, &definitions[0].name, sizeof(definitions[0]), def_len);
if (idx >= 0) {
// we did have a match
const char * key = definitions[idx].name;
switch (key[0]) {
// switch depending on the first char of the key, indicating the type
case '$': // string
be_pushstring(vm, (const char*) definitions[idx].value);
break;
case '&': // native function
be_pushntvfunction(vm, (bntvfunc) definitions[idx].value);
break;
default: // int
be_pushint(vm, definitions[idx].value);
break;
}
return btrue;
}
}
return bfalse;
}

View File

@ -3,8 +3,65 @@
#ifndef __BE_MAPPING__
#define __BE_MAPPING__
// include this header to force compilation fo this module
#ifdef __cplusplus
extern "C" {
#endif
#include "berry.h"
// include this header to force compilation fo this module
#define BE_MAX_CB 20 // max number of callbacks, each callback requires a distinct address
/*********************************************************************************************\
* Support for Berry int constants
* as virtual members
\*********************************************************************************************/
typedef intptr_t (*fn_any_callable)(intptr_t p0, intptr_t p1, intptr_t p2, intptr_t p3,
intptr_t p4, intptr_t p5, intptr_t p6, intptr_t p7);
typedef struct be_const_member_t {
const char * name;
int value;
} be_const_member_t;
// table of functions per class
typedef struct be_ntv_func_def_t {
const char * name;
void * func;
const char * return_type;
const char * arg_type;
} be_ntv_func_def_t;
struct bclass;
// list of classes and function tables
typedef struct be_ntv_class_def_t {
const char * name;
const struct bclass * cl;
const be_ntv_func_def_t * func_table;
size_t size;
} be_ntv_class_def_t;
void be_raisef(bvm *vm, const char *except, const char *msg, ...);
void be_set_gen_cb_name(bvm *vm, const char * gen_cb);
extern void be_map_insert_int(bvm *vm, const char *key, bint value);
extern void be_map_insert_bool(bvm *vm, const char *key, bbool value);
extern void be_map_insert_real(bvm *vm, const char *key, breal value);
extern void be_map_insert_str(bvm *vm, const char *key, const char *value);
extern void be_map_insert_list_uint8(bvm *vm, const char *key, const uint8_t *value, size_t size);
extern int be_map_bin_search(const char * needle, const void * table, size_t elt_size, size_t total_elements);
extern void be_create_class_wrapper(bvm *vm, const char * class_name, void * ptr);
extern int be_find_global_or_module_member(bvm *vm, const char * cl_name);
extern bbool be_const_member(bvm *vm, const be_const_member_t * definitions, size_t def_len);
extern intptr_t be_convert_single_elt(bvm *vm, int idx, const char * arg_type, const char * gen_cb);
extern void be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, intptr_t p[8]);;
extern int be_call_c_func(bvm *vm, void * func, const char * return_type, const char * arg_type);
#ifdef __cplusplus
}
#endif
#endif // __BE_MAPPING__

View File

@ -0,0 +1,97 @@
#include "be_mapping.h"
#include <string.h>
#include <math.h>
/*********************************************************************************************\
* Helper functions to create a map with single line calls
\*********************************************************************************************/
/* Insert an int to a key */
void be_map_insert_int(bvm *vm, const char *key, bint value)
{
be_pushstring(vm, key);
be_pushint(vm, value);
be_data_insert(vm, -3);
be_pop(vm, 2);
}
/* Insert an bbool to a key */
void be_map_insert_bool(bvm *vm, const char *key, bbool value)
{
be_pushstring(vm, key);
be_pushbool(vm, value);
be_data_insert(vm, -3);
be_pop(vm, 2);
}
/* Insert an real to a key */
/* if value == NAN, ignore */
void be_map_insert_real(bvm *vm, const char *key, breal value)
{
if (!isnan(value)) {
be_pushstring(vm, key);
be_pushreal(vm, value);
be_data_insert(vm, -3);
be_pop(vm, 2);
}
}
/* Insert an C string to a key */
void be_map_insert_str(bvm *vm, const char *key, const char *value)
{
be_pushstring(vm, key);
be_pushstring(vm, value);
be_data_insert(vm, -3);
be_pop(vm, 2);
}
/* Insert list of bytes as individual integers to a key */
void be_map_insert_list_uint8(bvm *vm, const char *key, const uint8_t *value, size_t size)
{
be_pushstring(vm, key);
be_newobject(vm, "list");
for (uint32_t i=0; i < size; i++) {
be_pushint(vm, value[i]);
be_data_push(vm, -2);
be_pop(vm, 1);
}
be_pop(vm, 1); // now list is on top
be_data_insert(vm, -3); // insert into map, key/value
be_pop(vm, 2); // pop both key and value
}
/*********************************************************************************************\
* Binary search for dynamic attributes
*
* Names need to be sorted
\*********************************************************************************************/
// binary search within an array of sorted strings
// the first 4 bytes are a pointer to a string
// returns 0..total_elements-1 or -1 if not found
//
// This version skips the first character of the string if it's not a letter,
// the first character is used to indicate the type of the value associated to the key
int be_map_bin_search(const char * needle, const void * table, size_t elt_size, size_t total_elements) {
int low = 0;
int high = total_elements - 1;
int mid = (low + high) / 2;
// start a dissect
while (low <= high) {
const char * elt = *(const char **) ( ((uint8_t*)table) + mid * elt_size );
char first_char = elt[0];
if ( !(first_char >= 'a' && first_char <='z') && !(first_char >= 'A' && first_char <='Z') ) {
elt++; // skip first char
}
int comp = strcmp(needle, elt);
if (comp < 0) {
high = mid - 1;
} else if (comp > 0) {
low = mid + 1;
} else {
break;
}
mid = (low + high) / 2;
}
if (low <= high) {
return mid;
} else {
return -1;
}
}

View File

@ -0,0 +1,22 @@
/*********************************************************************************************\
* Extended version of be_raise()
\*********************************************************************************************/
#include "be_mapping.h"
#include "be_exec.h"
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
// variant of be_raise with string format
void be_raisef(bvm *vm, const char *except, const char *msg, ...) {
// To save stack space support logging for max text length of 128 characters
char log_data[128];
va_list arg;
va_start(arg, msg);
uint32_t len = vsnprintf(log_data, sizeof(log_data)-3, msg, arg);
va_end(arg);
if (len+3 > sizeof(log_data)) { strcat(log_data, "..."); } // Actual data is more
be_raise(vm, except, log_data);
}

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,368 @@
# ESP32 Camera Driver
[![Build examples](https://github.com/espressif/esp32-camera/actions/workflows/build.yml/badge.svg)](https://github.com/espressif/esp32-camera/actions/workflows/build.yml)
## General Information
This repository hosts ESP32 series Soc compatible driver for image sensors. Additionally it provides a few tools, which allow converting the captured frame data to the more common BMP and JPEG formats.
### Supported Soc
- ESP32
- ESP32-S2
- ESP32-S3
### Supported Sensor
| model | max resolution | color type | output format | Len Size |
| ------- | -------------- | ---------- | ------------------------------------------------------------ | -------- |
| OV2640 | 1600 x 1200 | color | YUV(422/420)/YCbCr422<br>RGB565/555<br>8-bit compressed data<br>8/10-bit Raw RGB data | 1/4" |
| OV3660 | 2048 x 1536 | color | raw RGB data<br/>RGB565/555/444<br/>CCIR656<br/>YCbCr422<br/>compression | 1/5" |
| OV5640 | 2592 x 1944 | color | RAW RGB<br/>RGB565/555/444<br/>CCIR656<br/>YUV422/420<br/>YCbCr422<br/>compression | 1/4" |
| OV7670 | 640 x 480 | color | Raw Bayer RGB<br/>Processed Bayer RGB<br>YUV/YCbCr422<br>GRB422<br>RGB565/555 | 1/6" |
| OV7725 | 640 x 480 | color | Raw RGB<br/>GRB 422<br/>RGB565/555/444<br/>YCbCr 422 | 1/4" |
| NT99141 | 1280 x 720 | color | YCbCr 422<br/>RGB565/555/444<br/>Raw<br/>CCIR656<br/>JPEG compression | 1/4" |
| GC032A | 640 x 480 | color | YUV/YCbCr422<br/>RAW Bayer<br/>RGB565 | 1/10" |
| GC0308 | 640 x 480 | color | YUV/YCbCr422<br/>RAW Bayer<br/>RGB565 | 1/6.5" |
| GC2145 | 1600 x 1200 | color | YUV/YCbCr422<br/>RAW Bayer<br/>RGB565 | 1/5" |
## Important to Remember
- Except when using CIF or lower resolution with JPEG, the driver requires PSRAM to be installed and activated.
- Using YUV or RGB puts a lot of strain on the chip because writing to PSRAM is not particularly fast. The result is that image data might be missing. This is particularly true if WiFi is enabled. If you need RGB data, it is recommended that JPEG is captured and then turned into RGB using `fmt2rgb888` or `fmt2bmp`/`frame2bmp`.
- When 1 frame buffer is used, the driver will wait for the current frame to finish (VSYNC) and start I2S DMA. After the frame is acquired, I2S will be stopped and the frame buffer returned to the application. This approach gives more control over the system, but results in longer time to get the frame.
- When 2 or more frame bufers are used, I2S is running in continuous mode and each frame is pushed to a queue that the application can access. This approach puts more strain on the CPU/Memory, but allows for double the frame rate. Please use only with JPEG.
## Installation Instructions
### Using esp-idf
- Clone or download and extract the repository to the components folder of your ESP-IDF project
- Enable PSRAM in `menuconfig` (also set Flash and PSRAM frequiencies to 80MHz)
- Include `esp_camera.h` in your code
### Using PlatformIO
The easy way -- on the `env` section of `platformio.ini`, add the following:
```ini
[env]
lib_deps =
esp32-camera
```
Now the `esp_camera.h` is available to be included:
```c
#include "esp_camera.h"
```
Enable PSRAM on `menuconfig` or type it direclty on `sdkconfig`. Check the [official doc](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/kconfig.html#config-esp32-spiram-support) for more info.
```
CONFIG_ESP32_SPIRAM_SUPPORT=y
```
***Arduino*** The easy-way (content above) only seems to work if you're using `framework=arduino` which seems to take a bunch of the guesswork out (thanks Arduino!) but also suck up a lot more memory and flash, almost crippling the performance. If you plan to use the `framework=espidf` then read the sections below carefully!!
## Platform.io lib/submodule (for framework=espidf)
It's probably easier to just skip the platform.io library registry version and link the git repo as a submodule. (i.e. using code outside the platform.io library management). In this example we will install this as a submodule inside the platform.io $project/lib folder:
```
cd $project\lib
git submodule add -b master https://github.com/espressif/esp32-camera.git
```
Then in `platformio.ini` file
```
build_flags =
-I../lib/esp32-camera
```
After that `#include "esp_camera.h"` statement will be available. Now the module is included, and you're hopefully back to the same place as the easy-Arduino way.
**Warning about platform.io/espidf and fresh (not initialized) git repos**
There is a sharp-edge on you'll discover in the platform.io build process (in espidf v3.3 & 4.0.1) where a project which has only had `git init` but nothing committed will crash platform.io build process with highly non-useful output. The cause is due to lack of a version (making you think you did something wrong, when you didn't at all) - the output is horribly non-descript. Solution: the devs want you to create a file called version.txt with a number in it, or simply commit any file to the projects git repo and use git. This happens because platform.io build process tries to be too clever and determine the build version number from the git repo - it's a sharp edge you'll only encounter if you're experimenting on a new project with no commits .. like wtf is my camera not working let's try a 'clean project'?! </rant>
## Platform.io Kconfig
Kconfig is used by the platform.io menuconfig (accessed by running: `pio run -t menuconfig`) to interactively manage the various #ifdef statements throughout the espidf and supporting libraries (i.e. this repo: esp32-camera and arduino-esp32.git). The menuconfig process generates the `sdkconfig` file which is ultimately used behind the scenes by espidf compile+build process.
**Make sure to append or symlink** [this `Kconfig`](./Kconfig) content into the `Kconfig` of your project.
You symlink (or copy) the included Kconfig into your platform.io projects src directory. The file should be named `Kconfig.projbuild` in your projects src\ directory or you could also add the library path to a CMakefile.txt and hope the `Kconfig` (or `Kconfig.projbuild`) gets discovered by the menuconfig process, though this unpredictable for me.
The unpredictable wonky behavior in platform.io build process around Kconfig naming (Kconfig vs. Kconfig.projbuild) occurs between espidf versions 3.3 and 4.0 - but if you don't see "Camera configuration" in your `pio run -t menuconfig` then there is no point trying to test camera code (it may compile, but it probably won't work!) and it seems the platform.io devs (when they built their wrapper around the espidf menuconfig) didn't implement it properly. You've probably already figured out you can't use the espidf build tools since the files are in totally different locations and also different versions with sometimes different syntax. This is one of those times you might consider changing the `platformio.ini` from `platform=espressif32` to `platform=https://github.com/platformio/platform-espressif32.git#develop` to get a more recent version of the espidf 4.0 tools.
However with a bit of patience and experimenting you'll figure the Kconfig out. Once Kconfig (or Kconfig.projbuild) is working then you will be able to choose the configurations according to your setup or the camera libraries will be compiled. Although you might also need to delete your .pio/build directory before the options appear .. again, the `pio run -t menuconfig` doens't always notice the new Kconfig files!
If you miss-skip-ignore this critical step the camera module will compile but camera logic inside the library will be 'empty' because the Kconfig sets the proper #ifdef statements during the build process to initialize the selected cameras. It's very not optional!
## Examples
### Initialization
```c
#include "esp_camera.h"
//WROVER-KIT PIN Map
#define CAM_PIN_PWDN -1 //power down is not used
#define CAM_PIN_RESET -1 //software reset will be performed
#define CAM_PIN_XCLK 21
#define CAM_PIN_SIOD 26
#define CAM_PIN_SIOC 27
#define CAM_PIN_D7 35
#define CAM_PIN_D6 34
#define CAM_PIN_D5 39
#define CAM_PIN_D4 36
#define CAM_PIN_D3 19
#define CAM_PIN_D2 18
#define CAM_PIN_D1 5
#define CAM_PIN_D0 4
#define CAM_PIN_VSYNC 25
#define CAM_PIN_HREF 23
#define CAM_PIN_PCLK 22
static camera_config_t camera_config = {
.pin_pwdn = CAM_PIN_PWDN,
.pin_reset = CAM_PIN_RESET,
.pin_xclk = CAM_PIN_XCLK,
.pin_sscb_sda = CAM_PIN_SIOD,
.pin_sscb_scl = CAM_PIN_SIOC,
.pin_d7 = CAM_PIN_D7,
.pin_d6 = CAM_PIN_D6,
.pin_d5 = CAM_PIN_D5,
.pin_d4 = CAM_PIN_D4,
.pin_d3 = CAM_PIN_D3,
.pin_d2 = CAM_PIN_D2,
.pin_d1 = CAM_PIN_D1,
.pin_d0 = CAM_PIN_D0,
.pin_vsync = CAM_PIN_VSYNC,
.pin_href = CAM_PIN_HREF,
.pin_pclk = CAM_PIN_PCLK,
.xclk_freq_hz = 20000000,//EXPERIMENTAL: Set to 16MHz on ESP32-S2 or ESP32-S3 to enable EDMA mode
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_JPEG,//YUV422,GRAYSCALE,RGB565,JPEG
.frame_size = FRAMESIZE_UXGA,//QQVGA-QXGA Do not use sizes above QVGA when not JPEG
.jpeg_quality = 12, //0-63 lower number means higher quality
.fb_count = 1, //if more than one, i2s runs in continuous mode. Use only with JPEG
.grab_mode = CAMERA_GRAB_WHEN_EMPTY//CAMERA_GRAB_LATEST. Sets when buffers should be filled
};
esp_err_t camera_init(){
//power up the camera if PWDN pin is defined
if(CAM_PIN_PWDN != -1){
pinMode(CAM_PIN_PWDN, OUTPUT);
digitalWrite(CAM_PIN_PWDN, LOW);
}
//initialize the camera
esp_err_t err = esp_camera_init(&camera_config);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Camera Init Failed");
return err;
}
return ESP_OK;
}
esp_err_t camera_capture(){
//acquire a frame
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAG, "Camera Capture Failed");
return ESP_FAIL;
}
//replace this with your own function
process_image(fb->width, fb->height, fb->format, fb->buf, fb->len);
//return the frame buffer back to the driver for reuse
esp_camera_fb_return(fb);
return ESP_OK;
}
```
### JPEG HTTP Capture
```c
#include "esp_camera.h"
#include "esp_http_server.h"
#include "esp_timer.h"
typedef struct {
httpd_req_t *req;
size_t len;
} jpg_chunking_t;
static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len){
jpg_chunking_t *j = (jpg_chunking_t *)arg;
if(!index){
j->len = 0;
}
if(httpd_resp_send_chunk(j->req, (const char *)data, len) != ESP_OK){
return 0;
}
j->len += len;
return len;
}
esp_err_t jpg_httpd_handler(httpd_req_t *req){
camera_fb_t * fb = NULL;
esp_err_t res = ESP_OK;
size_t fb_len = 0;
int64_t fr_start = esp_timer_get_time();
fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAG, "Camera capture failed");
httpd_resp_send_500(req);
return ESP_FAIL;
}
res = httpd_resp_set_type(req, "image/jpeg");
if(res == ESP_OK){
res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg");
}
if(res == ESP_OK){
if(fb->format == PIXFORMAT_JPEG){
fb_len = fb->len;
res = httpd_resp_send(req, (const char *)fb->buf, fb->len);
} else {
jpg_chunking_t jchunk = {req, 0};
res = frame2jpg_cb(fb, 80, jpg_encode_stream, &jchunk)?ESP_OK:ESP_FAIL;
httpd_resp_send_chunk(req, NULL, 0);
fb_len = jchunk.len;
}
}
esp_camera_fb_return(fb);
int64_t fr_end = esp_timer_get_time();
ESP_LOGI(TAG, "JPG: %uKB %ums", (uint32_t)(fb_len/1024), (uint32_t)((fr_end - fr_start)/1000));
return res;
}
```
### JPEG HTTP Stream
```c
#include "esp_camera.h"
#include "esp_http_server.h"
#include "esp_timer.h"
#define PART_BOUNDARY "123456789000000000000987654321"
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
esp_err_t jpg_stream_httpd_handler(httpd_req_t *req){
camera_fb_t * fb = NULL;
esp_err_t res = ESP_OK;
size_t _jpg_buf_len;
uint8_t * _jpg_buf;
char * part_buf[64];
static int64_t last_frame = 0;
if(!last_frame) {
last_frame = esp_timer_get_time();
}
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
if(res != ESP_OK){
return res;
}
while(true){
fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAG, "Camera capture failed");
res = ESP_FAIL;
break;
}
if(fb->format != PIXFORMAT_JPEG){
bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
if(!jpeg_converted){
ESP_LOGE(TAG, "JPEG compression failed");
esp_camera_fb_return(fb);
res = ESP_FAIL;
}
} else {
_jpg_buf_len = fb->len;
_jpg_buf = fb->buf;
}
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
}
if(res == ESP_OK){
size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
}
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
}
if(fb->format != PIXFORMAT_JPEG){
free(_jpg_buf);
}
esp_camera_fb_return(fb);
if(res != ESP_OK){
break;
}
int64_t fr_end = esp_timer_get_time();
int64_t frame_time = fr_end - last_frame;
last_frame = fr_end;
frame_time /= 1000;
ESP_LOGI(TAG, "MJPG: %uKB %ums (%.1ffps)",
(uint32_t)(_jpg_buf_len/1024),
(uint32_t)frame_time, 1000.0 / (uint32_t)frame_time);
}
last_frame = 0;
return res;
}
```
### BMP HTTP Capture
```c
#include "esp_camera.h"
#include "esp_http_server.h"
#include "esp_timer.h"
esp_err_t bmp_httpd_handler(httpd_req_t *req){
camera_fb_t * fb = NULL;
esp_err_t res = ESP_OK;
int64_t fr_start = esp_timer_get_time();
fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAG, "Camera capture failed");
httpd_resp_send_500(req);
return ESP_FAIL;
}
uint8_t * buf = NULL;
size_t buf_len = 0;
bool converted = frame2bmp(fb, &buf, &buf_len);
esp_camera_fb_return(fb);
if(!converted){
ESP_LOGE(TAG, "BMP conversion failed");
httpd_resp_send_500(req);
return ESP_FAIL;
}
res = httpd_resp_set_type(req, "image/x-windows-bmp")
|| httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.bmp")
|| httpd_resp_send(req, (const char *)buf, buf_len);
free(buf);
int64_t fr_end = esp_timer_get_time();
ESP_LOGI(TAG, "BMP: %uKB %ums", (uint32_t)(buf_len/1024), (uint32_t)((fr_end - fr_start)/1000));
return res;
}
```

View File

@ -0,0 +1,60 @@
// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "esp_camera.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Uninitialize the lcd_cam module
*
* @param handle Provide handle pointer to release resources
*
* @return
* - ESP_OK Success
* - ESP_FAIL Uninitialize fail
*/
esp_err_t cam_deinit(void);
/**
* @brief Initialize the lcd_cam module
*
* @param config Configurations - see lcd_cam_config_t struct
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM No memory to initialize lcd_cam
* - ESP_FAIL Initialize fail
*/
esp_err_t cam_init(const camera_config_t *config);
esp_err_t cam_config(const camera_config_t *config, framesize_t frame_size, uint16_t sensor_pid);
void cam_stop(void);
void cam_start(void);
camera_fb_t *cam_take(TickType_t timeout);
void cam_give(camera_fb_t *dma_buffer);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,214 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* Example Use
*
static camera_config_t camera_example_config = {
.pin_pwdn = PIN_PWDN,
.pin_reset = PIN_RESET,
.pin_xclk = PIN_XCLK,
.pin_sscb_sda = PIN_SIOD,
.pin_sscb_scl = PIN_SIOC,
.pin_d7 = PIN_D7,
.pin_d6 = PIN_D6,
.pin_d5 = PIN_D5,
.pin_d4 = PIN_D4,
.pin_d3 = PIN_D3,
.pin_d2 = PIN_D2,
.pin_d1 = PIN_D1,
.pin_d0 = PIN_D0,
.pin_vsync = PIN_VSYNC,
.pin_href = PIN_HREF,
.pin_pclk = PIN_PCLK,
.xclk_freq_hz = 20000000,
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_JPEG,
.frame_size = FRAMESIZE_SVGA,
.jpeg_quality = 10,
.fb_count = 2,
.grab_mode = CAMERA_GRAB_WHEN_EMPTY
};
esp_err_t camera_example_init(){
return esp_camera_init(&camera_example_config);
}
esp_err_t camera_example_capture(){
//capture a frame
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAG, "Frame buffer could not be acquired");
return ESP_FAIL;
}
//replace this with your own function
display_image(fb->width, fb->height, fb->pixformat, fb->buf, fb->len);
//return the frame buffer back to be reused
esp_camera_fb_return(fb);
return ESP_OK;
}
*/
#pragma once
#include "esp_err.h"
#include "driver/ledc.h"
#include "sensor.h"
#include "sys/time.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Configuration structure for camera initialization
*/
typedef enum {
CAMERA_GRAB_WHEN_EMPTY, /*!< Fills buffers when they are empty. Less resources but first 'fb_count' frames might be old */
CAMERA_GRAB_LATEST /*!< Except when 1 frame buffer is used, queue will always contain the last 'fb_count' frames */
} camera_grab_mode_t;
/**
* @brief Camera frame buffer location
*/
typedef enum {
CAMERA_FB_IN_PSRAM, /*!< Frame buffer is placed in external PSRAM */
CAMERA_FB_IN_DRAM /*!< Frame buffer is placed in internal DRAM */
} camera_fb_location_t;
/**
* @brief Configuration structure for camera initialization
*/
typedef struct {
int pin_pwdn; /*!< GPIO pin for camera power down line */
int pin_reset; /*!< GPIO pin for camera reset line */
int pin_xclk; /*!< GPIO pin for camera XCLK line */
int pin_sscb_sda; /*!< GPIO pin for camera SDA line */
int pin_sscb_scl; /*!< GPIO pin for camera SCL line */
int pin_d7; /*!< GPIO pin for camera D7 line */
int pin_d6; /*!< GPIO pin for camera D6 line */
int pin_d5; /*!< GPIO pin for camera D5 line */
int pin_d4; /*!< GPIO pin for camera D4 line */
int pin_d3; /*!< GPIO pin for camera D3 line */
int pin_d2; /*!< GPIO pin for camera D2 line */
int pin_d1; /*!< GPIO pin for camera D1 line */
int pin_d0; /*!< GPIO pin for camera D0 line */
int pin_vsync; /*!< GPIO pin for camera VSYNC line */
int pin_href; /*!< GPIO pin for camera HREF line */
int pin_pclk; /*!< GPIO pin for camera PCLK line */
int xclk_freq_hz; /*!< Frequency of XCLK signal, in Hz. EXPERIMENTAL: Set to 16MHz on ESP32-S2 or ESP32-S3 to enable EDMA mode */
ledc_timer_t ledc_timer; /*!< LEDC timer to be used for generating XCLK */
ledc_channel_t ledc_channel; /*!< LEDC channel to be used for generating XCLK */
pixformat_t pixel_format; /*!< Format of the pixel data: PIXFORMAT_ + YUV422|GRAYSCALE|RGB565|JPEG */
framesize_t frame_size; /*!< Size of the output image: FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA */
int jpeg_quality; /*!< Quality of JPEG output. 0-63 lower means higher quality */
size_t fb_count; /*!< Number of frame buffers to be allocated. If more than one, then each frame will be acquired (double speed) */
camera_fb_location_t fb_location; /*!< The location where the frame buffer will be allocated */
camera_grab_mode_t grab_mode; /*!< When buffers should be filled */
} camera_config_t;
/**
* @brief Data structure of camera frame buffer
*/
typedef struct {
uint8_t * buf; /*!< Pointer to the pixel data */
size_t len; /*!< Length of the buffer in bytes */
size_t width; /*!< Width of the buffer in pixels */
size_t height; /*!< Height of the buffer in pixels */
pixformat_t format; /*!< Format of the pixel data */
struct timeval timestamp; /*!< Timestamp since boot of the first DMA buffer of the frame */
} camera_fb_t;
#define ESP_ERR_CAMERA_BASE 0x20000
#define ESP_ERR_CAMERA_NOT_DETECTED (ESP_ERR_CAMERA_BASE + 1)
#define ESP_ERR_CAMERA_FAILED_TO_SET_FRAME_SIZE (ESP_ERR_CAMERA_BASE + 2)
#define ESP_ERR_CAMERA_FAILED_TO_SET_OUT_FORMAT (ESP_ERR_CAMERA_BASE + 3)
#define ESP_ERR_CAMERA_NOT_SUPPORTED (ESP_ERR_CAMERA_BASE + 4)
/**
* @brief Initialize the camera driver
*
* @note call camera_probe before calling this function
*
* This function detects and configures camera over I2C interface,
* allocates framebuffer and DMA buffers,
* initializes parallel I2S input, and sets up DMA descriptors.
*
* Currently this function can only be called once and there is
* no way to de-initialize this module.
*
* @param config Camera configuration parameters
*
* @return ESP_OK on success
*/
esp_err_t esp_camera_init(const camera_config_t* config);
/**
* @brief Deinitialize the camera driver
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if the driver hasn't been initialized yet
*/
esp_err_t esp_camera_deinit();
/**
* @brief Obtain pointer to a frame buffer.
*
* @return pointer to the frame buffer
*/
camera_fb_t* esp_camera_fb_get();
/**
* @brief Return the frame buffer to be reused again.
*
* @param fb Pointer to the frame buffer
*/
void esp_camera_fb_return(camera_fb_t * fb);
/**
* @brief Get a pointer to the image sensor control structure
*
* @return pointer to the sensor
*/
sensor_t * esp_camera_sensor_get();
/**
* @brief Save camera settings to non-volatile-storage (NVS)
*
* @param key A unique nvs key name for the camera settings
*/
esp_err_t esp_camera_save_to_nvs(const char *key);
/**
* @brief Load camera settings from non-volatile-storage (NVS)
*
* @param key A unique nvs key name for the camera settings
*/
esp_err_t esp_camera_load_from_nvs(const char *key);
#ifdef __cplusplus
}
#endif
#include "img_converters.h"

View File

@ -0,0 +1,245 @@
/*
* This file is part of the OpenMV project.
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* Sensor abstraction layer.
*
*/
#ifndef __SENSOR_H__
#define __SENSOR_H__
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
OV9650_PID = 0x96,
OV7725_PID = 0x77,
OV2640_PID = 0x26,
OV3660_PID = 0x3660,
OV5640_PID = 0x5640,
OV7670_PID = 0x76,
NT99141_PID = 0x1410,
GC2145_PID = 0x2145,
GC032A_PID = 0x232a,
GC0308_PID = 0x9b,
} camera_pid_t;
typedef enum {
CAMERA_OV7725,
CAMERA_OV2640,
CAMERA_OV3660,
CAMERA_OV5640,
CAMERA_OV7670,
CAMERA_NT99141,
CAMERA_GC2145,
CAMERA_GC032A,
CAMERA_GC0308,
CAMERA_MODEL_MAX,
CAMERA_NONE,
} camera_model_t;
typedef enum {
OV2640_SCCB_ADDR = 0x30,// 0x60 >> 1
OV5640_SCCB_ADDR = 0x3C,// 0x78 >> 1
OV3660_SCCB_ADDR = 0x3C,// 0x78 >> 1
OV7725_SCCB_ADDR = 0x21,// 0x42 >> 1
OV7670_SCCB_ADDR = 0x21,// 0x42 >> 1
NT99141_SCCB_ADDR = 0x2A,// 0x54 >> 1
GC2145_SCCB_ADDR = 0x3C,// 0x78 >> 1
GC032A_SCCB_ADDR = 0x21,// 0x42 >> 1
GC0308_SCCB_ADDR = 0x21,// 0x42 >> 1
} camera_sccb_addr_t;
typedef enum {
PIXFORMAT_RGB565, // 2BPP/RGB565
PIXFORMAT_YUV422, // 2BPP/YUV422
PIXFORMAT_GRAYSCALE, // 1BPP/GRAYSCALE
PIXFORMAT_JPEG, // JPEG/COMPRESSED
PIXFORMAT_RGB888, // 3BPP/RGB888
PIXFORMAT_RAW, // RAW
PIXFORMAT_RGB444, // 3BP2P/RGB444
PIXFORMAT_RGB555, // 3BP2P/RGB555
} pixformat_t;
typedef enum {
FRAMESIZE_96X96, // 96x96
FRAMESIZE_QQVGA, // 160x120
FRAMESIZE_QCIF, // 176x144
FRAMESIZE_HQVGA, // 240x176
FRAMESIZE_240X240, // 240x240
FRAMESIZE_QVGA, // 320x240
FRAMESIZE_CIF, // 400x296
FRAMESIZE_HVGA, // 480x320
FRAMESIZE_VGA, // 640x480
FRAMESIZE_SVGA, // 800x600
FRAMESIZE_XGA, // 1024x768
FRAMESIZE_HD, // 1280x720
FRAMESIZE_SXGA, // 1280x1024
FRAMESIZE_UXGA, // 1600x1200
// 3MP Sensors
FRAMESIZE_FHD, // 1920x1080
FRAMESIZE_P_HD, // 720x1280
FRAMESIZE_P_3MP, // 864x1536
FRAMESIZE_QXGA, // 2048x1536
// 5MP Sensors
FRAMESIZE_QHD, // 2560x1440
FRAMESIZE_WQXGA, // 2560x1600
FRAMESIZE_P_FHD, // 1080x1920
FRAMESIZE_QSXGA, // 2560x1920
FRAMESIZE_INVALID
} framesize_t;
typedef struct {
const camera_model_t model;
const char *name;
const camera_sccb_addr_t sccb_addr;
const camera_pid_t pid;
const framesize_t max_size;
const bool support_jpeg;
} camera_sensor_info_t;
typedef enum {
ASPECT_RATIO_4X3,
ASPECT_RATIO_3X2,
ASPECT_RATIO_16X10,
ASPECT_RATIO_5X3,
ASPECT_RATIO_16X9,
ASPECT_RATIO_21X9,
ASPECT_RATIO_5X4,
ASPECT_RATIO_1X1,
ASPECT_RATIO_9X16
} aspect_ratio_t;
typedef enum {
GAINCEILING_2X,
GAINCEILING_4X,
GAINCEILING_8X,
GAINCEILING_16X,
GAINCEILING_32X,
GAINCEILING_64X,
GAINCEILING_128X,
} gainceiling_t;
typedef struct {
uint16_t max_width;
uint16_t max_height;
uint16_t start_x;
uint16_t start_y;
uint16_t end_x;
uint16_t end_y;
uint16_t offset_x;
uint16_t offset_y;
uint16_t total_x;
uint16_t total_y;
} ratio_settings_t;
typedef struct {
const uint16_t width;
const uint16_t height;
const aspect_ratio_t aspect_ratio;
} resolution_info_t;
// Resolution table (in sensor.c)
extern const resolution_info_t resolution[];
// camera sensor table (in sensor.c)
extern const camera_sensor_info_t camera_sensor[];
typedef struct {
uint8_t MIDH;
uint8_t MIDL;
uint16_t PID;
uint8_t VER;
} sensor_id_t;
typedef struct {
framesize_t framesize;//0 - 10
bool scale;
bool binning;
uint8_t quality;//0 - 63
int8_t brightness;//-2 - 2
int8_t contrast;//-2 - 2
int8_t saturation;//-2 - 2
int8_t sharpness;//-2 - 2
uint8_t denoise;
uint8_t special_effect;//0 - 6
uint8_t wb_mode;//0 - 4
uint8_t awb;
uint8_t awb_gain;
uint8_t aec;
uint8_t aec2;
int8_t ae_level;//-2 - 2
uint16_t aec_value;//0 - 1200
uint8_t agc;
uint8_t agc_gain;//0 - 30
uint8_t gainceiling;//0 - 6
uint8_t bpc;
uint8_t wpc;
uint8_t raw_gma;
uint8_t lenc;
uint8_t hmirror;
uint8_t vflip;
uint8_t dcw;
uint8_t colorbar;
} camera_status_t;
typedef struct _sensor sensor_t;
typedef struct _sensor {
sensor_id_t id; // Sensor ID.
uint8_t slv_addr; // Sensor I2C slave address.
pixformat_t pixformat;
camera_status_t status;
int xclk_freq_hz;
// Sensor function pointers
int (*init_status) (sensor_t *sensor);
int (*reset) (sensor_t *sensor);
int (*set_pixformat) (sensor_t *sensor, pixformat_t pixformat);
int (*set_framesize) (sensor_t *sensor, framesize_t framesize);
int (*set_contrast) (sensor_t *sensor, int level);
int (*set_brightness) (sensor_t *sensor, int level);
int (*set_saturation) (sensor_t *sensor, int level);
int (*set_sharpness) (sensor_t *sensor, int level);
int (*set_denoise) (sensor_t *sensor, int level);
int (*set_gainceiling) (sensor_t *sensor, gainceiling_t gainceiling);
int (*set_quality) (sensor_t *sensor, int quality);
int (*set_colorbar) (sensor_t *sensor, int enable);
int (*set_whitebal) (sensor_t *sensor, int enable);
int (*set_gain_ctrl) (sensor_t *sensor, int enable);
int (*set_exposure_ctrl) (sensor_t *sensor, int enable);
int (*set_hmirror) (sensor_t *sensor, int enable);
int (*set_vflip) (sensor_t *sensor, int enable);
int (*set_aec2) (sensor_t *sensor, int enable);
int (*set_awb_gain) (sensor_t *sensor, int enable);
int (*set_agc_gain) (sensor_t *sensor, int gain);
int (*set_aec_value) (sensor_t *sensor, int gain);
int (*set_special_effect) (sensor_t *sensor, int effect);
int (*set_wb_mode) (sensor_t *sensor, int mode);
int (*set_ae_level) (sensor_t *sensor, int level);
int (*set_dcw) (sensor_t *sensor, int enable);
int (*set_bpc) (sensor_t *sensor, int enable);
int (*set_wpc) (sensor_t *sensor, int enable);
int (*set_raw_gma) (sensor_t *sensor, int enable);
int (*set_lenc) (sensor_t *sensor, int enable);
int (*get_reg) (sensor_t *sensor, int reg, int mask);
int (*set_reg) (sensor_t *sensor, int reg, int mask, int value);
int (*set_res_raw) (sensor_t *sensor, int startX, int startY, int endX, int endY, int offsetX, int offsetY, int totalX, int totalY, int outputX, int outputY, bool scale, bool binning);
int (*set_pll) (sensor_t *sensor, int bypass, int mul, int sys, int root, int pre, int seld5, int pclken, int pclk);
int (*set_xclk) (sensor_t *sensor, int timer, int xclk);
} sensor_t;
camera_sensor_info_t *esp_camera_sensor_get_info(sensor_id_t *id);
#ifdef __cplusplus
}
#endif
#endif /* __SENSOR_H__ */

View File

@ -0,0 +1,9 @@
#pragma once
#include "esp_system.h"
esp_err_t xclk_timer_conf(int ledc_timer, int xclk_freq_hz);
esp_err_t camera_enable_out_clock();
void camera_disable_out_clock();

View File

@ -0,0 +1,20 @@
{
"name": "esp32-camera-header",
"version": "1.0.0",
"keywords": "esp32, camera, espressif, esp32-cam",
"description": "ESP32 camera header files",
"repository": {
"type": "git",
"url": "https://github.com/espressif/esp32-camera"
},
"frameworks": "arduino",
"platforms": "espressif32",
"build": {
"flags": [
"-Idriver/include"
],
"includeDir": ".",
"srcDir": ".",
"srcFilter": ["-<*>", "+<driver>"]
}
}

View File

@ -8,6 +8,6 @@
"type": "git",
"url": "https://github.com/pfalcon/re1.5"
},
"frameworks": "*",
"platforms": "*"
"frameworks": "arduino",
"platforms": "espressif32"
}

View File

@ -8,8 +8,8 @@
"type": "git",
"url": "https://gitlab.freedesktop.org/freetype"
},
"frameworks": "*",
"platforms": "*",
"frameworks": "arduino",
"platforms": "espressif32",
"build": {
"srcFilter": [
"+<base/ftsystem.c>",

View File

@ -8,9 +8,10 @@ extern "C" {
#endif
#include "be_ctypes.h"
#include "be_mapping.h"
/* `lv_style` methods */
const lvbe_call_c_t lv_style_func[] = {
const be_ntv_func_def_t lv_style_func[] = {
{ "set_align", (void*) &lv_style_set_align, "", "(lv.lv_style)i" },
{ "set_anim_speed", (void*) &lv_style_set_anim_speed, "", "(lv.lv_style)i" },
{ "set_anim_time", (void*) &lv_style_set_anim_time, "", "(lv.lv_style)i" },
@ -103,20 +104,20 @@ const lvbe_call_c_t lv_style_func[] = {
};
/* `lv_font` methods */
const lvbe_call_c_t lv_font_func[] = {
const be_ntv_func_def_t lv_font_func[] = {
};
/* `lv_color` methods */
const lvbe_call_c_t lv_color_func[] = {
const be_ntv_func_def_t lv_color_func[] = {
};
/* `lv_theme` methods */
const lvbe_call_c_t lv_theme_func[] = {
const be_ntv_func_def_t lv_theme_func[] = {
};
/* `lv_img` methods */
#ifdef BE_LV_WIDGET_IMG
const lvbe_call_c_t lv_img_func[] = {
const be_ntv_func_def_t lv_img_func[] = {
{ "get_angle", (void*) &lv_img_get_angle, "i", "(lv.lv_obj)" },
{ "get_antialias", (void*) &lv_img_get_antialias, "b", "(lv.lv_obj)" },
{ "get_offset_x", (void*) &lv_img_get_offset_x, "i", "(lv.lv_obj)" },
@ -136,7 +137,7 @@ const lvbe_call_c_t lv_img_func[] = {
#endif // BE_LV_WIDGET_IMG
/* `lv_disp` methods */
const lvbe_call_c_t lv_disp_func[] = {
const be_ntv_func_def_t lv_disp_func[] = {
{ "clean_dcache", (void*) &lv_disp_clean_dcache, "", "(lv.lv_disp)" },
{ "dpx", (void*) &lv_disp_dpx, "i", "(lv.lv_disp)i" },
{ "get_inactive_time", (void*) &lv_disp_get_inactive_time, "i", "(lv.lv_disp)" },
@ -154,7 +155,7 @@ const lvbe_call_c_t lv_disp_func[] = {
};
/* `lv_obj` methods */
const lvbe_call_c_t lv_obj_func[] = {
const be_ntv_func_def_t lv_obj_func[] = {
{ "add_event_cb", (void*) &lv_obj_add_event_cb, "i", "(lv.lv_obj)^lv_event_cb^i." },
{ "add_flag", (void*) &lv_obj_add_flag, "", "(lv.lv_obj)i" },
{ "add_state", (void*) &lv_obj_add_state, "", "(lv.lv_obj)i" },
@ -458,7 +459,7 @@ const lvbe_call_c_t lv_obj_func[] = {
};
/* `lv_group` methods */
const lvbe_call_c_t lv_group_func[] = {
const be_ntv_func_def_t lv_group_func[] = {
{ "add_obj", (void*) &lv_group_add_obj, "", "(lv.lv_group)(lv.lv_obj)" },
{ "del", (void*) &lv_group_del, "", "(lv.lv_group)" },
{ "focus_freeze", (void*) &lv_group_focus_freeze, "", "(lv.lv_group)b" },
@ -481,7 +482,7 @@ const lvbe_call_c_t lv_group_func[] = {
};
/* `lv_indev` methods */
const lvbe_call_c_t lv_indev_func[] = {
const be_ntv_func_def_t lv_indev_func[] = {
{ "enable", (void*) &lv_indev_enable, "", "(lv.lv_indev)b" },
{ "get_gesture_dir", (void*) &lv_indev_get_gesture_dir, "i", "(lv.lv_indev)" },
{ "get_key", (void*) &lv_indev_get_key, "i", "(lv.lv_indev)" },
@ -501,7 +502,7 @@ const lvbe_call_c_t lv_indev_func[] = {
/* `lv_chart` methods */
#ifdef BE_LV_WIDGET_CHART
const lvbe_call_c_t lv_chart_func[] = {
const be_ntv_func_def_t lv_chart_func[] = {
{ "get_cursor_point", (void*) &lv_chart_get_cursor_point, "i", "(lv.lv_obj)(lv.lv_chart_cursor)" },
{ "get_point_count", (void*) &lv_chart_get_point_count, "i", "(lv.lv_obj)" },
{ "get_point_pos_by_id", (void*) &lv_chart_get_point_pos_by_id, "", "(lv.lv_obj)(lv.lv_chart_series)i(lv.lv_point)" },
@ -537,7 +538,7 @@ const lvbe_call_c_t lv_chart_func[] = {
/* `lv_colorwheel` methods */
#ifdef BE_LV_WIDGET_COLORWHEEL
const lvbe_call_c_t lv_colorwheel_func[] = {
const be_ntv_func_def_t lv_colorwheel_func[] = {
{ "get_color_mode", (void*) &lv_colorwheel_get_color_mode, "i", "(lv.lv_obj)" },
{ "get_color_mode_fixed", (void*) &lv_colorwheel_get_color_mode_fixed, "b", "(lv.lv_obj)" },
{ "get_hsv", (void*) &lv_colorwheel_get_hsv, "i", "(lv.lv_obj)" },
@ -551,14 +552,14 @@ const lvbe_call_c_t lv_colorwheel_func[] = {
/* `lv_imgbtn` methods */
#ifdef BE_LV_WIDGET_IMGBTN
const lvbe_call_c_t lv_imgbtn_func[] = {
const be_ntv_func_def_t lv_imgbtn_func[] = {
{ "set_src", (void*) &lv_imgbtn_set_src, "", "(lv.lv_obj)(lv.lv_imgbtn_state)..." },
};
#endif // BE_LV_WIDGET_IMGBTN
/* `lv_led` methods */
#ifdef BE_LV_WIDGET_LED
const lvbe_call_c_t lv_led_func[] = {
const be_ntv_func_def_t lv_led_func[] = {
{ "get_brightness", (void*) &lv_led_get_brightness, "i", "(lv.lv_obj)" },
{ "off", (void*) &lv_led_off, "", "(lv.lv_obj)" },
{ "on", (void*) &lv_led_on, "", "(lv.lv_obj)" },
@ -570,7 +571,7 @@ const lvbe_call_c_t lv_led_func[] = {
/* `lv_meter` methods */
#ifdef BE_LV_WIDGET_METER
const lvbe_call_c_t lv_meter_func[] = {
const be_ntv_func_def_t lv_meter_func[] = {
{ "add_arc", (void*) &lv_meter_add_arc, "lv.lv_meter_indicator", "(lv.lv_obj)(lv.lv_meter_scale)i(lv.lv_color)i" },
{ "add_needle_img", (void*) &lv_meter_add_needle_img, "lv.lv_meter_indicator", "(lv.lv_obj)(lv.lv_meter_scale).ii" },
{ "add_needle_line", (void*) &lv_meter_add_needle_line, "lv.lv_meter_indicator", "(lv.lv_obj)(lv.lv_meter_scale)i(lv.lv_color)i" },
@ -587,7 +588,7 @@ const lvbe_call_c_t lv_meter_func[] = {
/* `lv_msgbox` methods */
#ifdef BE_LV_WIDGET_MSGBOX
const lvbe_call_c_t lv_msgbox_func[] = {
const be_ntv_func_def_t lv_msgbox_func[] = {
{ "close", (void*) &lv_msgbox_close, "", "(lv.lv_obj)" },
{ "get_active_btn_text", (void*) &lv_msgbox_get_active_btn_text, "s", "(lv.lv_obj)" },
{ "get_btns", (void*) &lv_msgbox_get_btns, "lv.lv_obj", "(lv.lv_obj)" },
@ -599,7 +600,7 @@ const lvbe_call_c_t lv_msgbox_func[] = {
/* `lv_spinbox` methods */
#ifdef BE_LV_WIDGET_SPINBOX
const lvbe_call_c_t lv_spinbox_func[] = {
const be_ntv_func_def_t lv_spinbox_func[] = {
{ "decrement", (void*) &lv_spinbox_decrement, "", "(lv.lv_obj)" },
{ "get_rollover", (void*) &lv_spinbox_get_rollover, "b", "(lv.lv_obj)" },
{ "get_step", (void*) &lv_spinbox_get_step, "i", "(lv.lv_obj)" },
@ -617,13 +618,13 @@ const lvbe_call_c_t lv_spinbox_func[] = {
/* `lv_spinner` methods */
#ifdef BE_LV_WIDGET_SPINNER
const lvbe_call_c_t lv_spinner_func[] = {
const be_ntv_func_def_t lv_spinner_func[] = {
};
#endif // BE_LV_WIDGET_SPINNER
/* `lv_arc` methods */
#ifdef BE_LV_WIDGET_ARC
const lvbe_call_c_t lv_arc_func[] = {
const be_ntv_func_def_t lv_arc_func[] = {
{ "get_angle_end", (void*) &lv_arc_get_angle_end, "i", "(lv.lv_obj)" },
{ "get_angle_start", (void*) &lv_arc_get_angle_start, "i", "(lv.lv_obj)" },
{ "get_bg_angle_end", (void*) &lv_arc_get_bg_angle_end, "i", "(lv.lv_obj)" },
@ -648,7 +649,7 @@ const lvbe_call_c_t lv_arc_func[] = {
/* `lv_bar` methods */
#ifdef BE_LV_WIDGET_BAR
const lvbe_call_c_t lv_bar_func[] = {
const be_ntv_func_def_t lv_bar_func[] = {
{ "get_max_value", (void*) &lv_bar_get_max_value, "i", "(lv.lv_obj)" },
{ "get_min_value", (void*) &lv_bar_get_min_value, "i", "(lv.lv_obj)" },
{ "get_mode", (void*) &lv_bar_get_mode, "i", "(lv.lv_obj)" },
@ -663,13 +664,13 @@ const lvbe_call_c_t lv_bar_func[] = {
/* `lv_btn` methods */
#ifdef BE_LV_WIDGET_BTN
const lvbe_call_c_t lv_btn_func[] = {
const be_ntv_func_def_t lv_btn_func[] = {
};
#endif // BE_LV_WIDGET_BTN
/* `lv_btnmatrix` methods */
#ifdef BE_LV_WIDGET_BTNMATRIX
const lvbe_call_c_t lv_btnmatrix_func[] = {
const be_ntv_func_def_t lv_btnmatrix_func[] = {
{ "clear_btn_ctrl", (void*) &lv_btnmatrix_clear_btn_ctrl, "", "(lv.lv_obj)i(lv.lv_btnmatrix_ctrl)" },
{ "clear_btn_ctrl_all", (void*) &lv_btnmatrix_clear_btn_ctrl_all, "", "(lv.lv_obj)(lv.lv_btnmatrix_ctrl)" },
{ "get_btn_text", (void*) &lv_btnmatrix_get_btn_text, "s", "(lv.lv_obj)i" },
@ -688,7 +689,7 @@ const lvbe_call_c_t lv_btnmatrix_func[] = {
/* `lv_canvas` methods */
#ifdef BE_LV_WIDGET_CANVAS
const lvbe_call_c_t lv_canvas_func[] = {
const be_ntv_func_def_t lv_canvas_func[] = {
{ "blur_hor", (void*) &lv_canvas_blur_hor, "", "(lv.lv_obj)(lv.lv_area)i" },
{ "blur_ver", (void*) &lv_canvas_blur_ver, "", "(lv.lv_obj)(lv.lv_area)i" },
{ "copy_buf", (void*) &lv_canvas_copy_buf, "", "(lv.lv_obj).iiii" },
@ -709,7 +710,7 @@ const lvbe_call_c_t lv_canvas_func[] = {
/* `lv_checkbox` methods */
#ifdef BE_LV_WIDGET_CHECKBOX
const lvbe_call_c_t lv_checkbox_func[] = {
const be_ntv_func_def_t lv_checkbox_func[] = {
{ "get_text", (void*) &lv_checkbox_get_text, "s", "(lv.lv_obj)" },
{ "set_text", (void*) &lv_checkbox_set_text, "", "(lv.lv_obj)s" },
{ "set_text_static", (void*) &lv_checkbox_set_text_static, "", "(lv.lv_obj)s" },
@ -718,7 +719,7 @@ const lvbe_call_c_t lv_checkbox_func[] = {
/* `lv_dropdown` methods */
#ifdef BE_LV_WIDGET_DROPDOWN
const lvbe_call_c_t lv_dropdown_func[] = {
const be_ntv_func_def_t lv_dropdown_func[] = {
{ "add_option", (void*) &lv_dropdown_add_option, "", "(lv.lv_obj)si" },
{ "clear_options", (void*) &lv_dropdown_clear_options, "", "(lv.lv_obj)" },
{ "close", (void*) &lv_dropdown_close, "", "(lv.lv_obj)" },
@ -744,7 +745,7 @@ const lvbe_call_c_t lv_dropdown_func[] = {
/* `lv_label` methods */
#ifdef BE_LV_WIDGET_LABEL
const lvbe_call_c_t lv_label_func[] = {
const be_ntv_func_def_t lv_label_func[] = {
{ "cut_text", (void*) &lv_label_cut_text, "", "(lv.lv_obj)ii" },
{ "get_letter_on", (void*) &lv_label_get_letter_on, "i", "(lv.lv_obj)(lv.lv_point)" },
{ "get_letter_pos", (void*) &lv_label_get_letter_pos, "", "(lv.lv_obj)i(lv.lv_point)" },
@ -767,7 +768,7 @@ const lvbe_call_c_t lv_label_func[] = {
/* `lv_line` methods */
#ifdef BE_LV_WIDGET_LINE
const lvbe_call_c_t lv_line_func[] = {
const be_ntv_func_def_t lv_line_func[] = {
{ "get_y_invert", (void*) &lv_line_get_y_invert, "b", "(lv.lv_obj)" },
{ "set_points", (void*) &lv_line_set_points, "", "(lv.lv_obj)ii" },
{ "set_y_invert", (void*) &lv_line_set_y_invert, "", "(lv.lv_obj)b" },
@ -776,7 +777,7 @@ const lvbe_call_c_t lv_line_func[] = {
/* `lv_roller` methods */
#ifdef BE_LV_WIDGET_ROLLER
const lvbe_call_c_t lv_roller_func[] = {
const be_ntv_func_def_t lv_roller_func[] = {
{ "get_option_cnt", (void*) &lv_roller_get_option_cnt, "i", "(lv.lv_obj)" },
{ "get_options", (void*) &lv_roller_get_options, "s", "(lv.lv_obj)" },
{ "get_selected", (void*) &lv_roller_get_selected, "i", "(lv.lv_obj)" },
@ -789,7 +790,7 @@ const lvbe_call_c_t lv_roller_func[] = {
/* `lv_slider` methods */
#ifdef BE_LV_WIDGET_SLIDER
const lvbe_call_c_t lv_slider_func[] = {
const be_ntv_func_def_t lv_slider_func[] = {
{ "get_left_value", (void*) &lv_slider_get_left_value, "i", "(lv.lv_obj)" },
{ "get_max_value", (void*) &lv_slider_get_max_value, "i", "(lv.lv_obj)" },
{ "get_min_value", (void*) &lv_slider_get_min_value, "i", "(lv.lv_obj)" },
@ -805,13 +806,13 @@ const lvbe_call_c_t lv_slider_func[] = {
/* `lv_switch` methods */
#ifdef BE_LV_WIDGET_SWITCH
const lvbe_call_c_t lv_switch_func[] = {
const be_ntv_func_def_t lv_switch_func[] = {
};
#endif // BE_LV_WIDGET_SWITCH
/* `lv_table` methods */
#ifdef BE_LV_WIDGET_TABLE
const lvbe_call_c_t lv_table_func[] = {
const be_ntv_func_def_t lv_table_func[] = {
{ "add_cell_ctrl", (void*) &lv_table_add_cell_ctrl, "", "(lv.lv_obj)ii(lv.lv_table_cell_ctrl)" },
{ "clear_cell_ctrl", (void*) &lv_table_clear_cell_ctrl, "", "(lv.lv_obj)ii(lv.lv_table_cell_ctrl)" },
{ "get_cell_value", (void*) &lv_table_get_cell_value, "s", "(lv.lv_obj)ii" },
@ -830,7 +831,7 @@ const lvbe_call_c_t lv_table_func[] = {
/* `lv_textarea` methods */
#ifdef BE_LV_WIDGET_TEXTAREA
const lvbe_call_c_t lv_textarea_func[] = {
const be_ntv_func_def_t lv_textarea_func[] = {
{ "add_char", (void*) &lv_textarea_add_char, "", "(lv.lv_obj)i" },
{ "add_text", (void*) &lv_textarea_add_text, "", "(lv.lv_obj)s" },
{ "clear_selection", (void*) &lv_textarea_clear_selection, "", "(lv.lv_obj)" },
@ -901,7 +902,7 @@ extern const bclass be_class_lv_theme;
// map of clases
const lvbe_call_c_classes_t lv_classes[] = {
const be_ntv_class_def_t lv_classes[] = {
#ifdef BE_LV_WIDGET_ARC
{ "lv_arc", &be_class_lv_arc, lv_arc_func, sizeof(lv_arc_func) / sizeof(lv_arc_func[0]) },
#endif // BE_LV_WIDGET_ARC
@ -988,106 +989,106 @@ const size_t lv_classes_size = sizeof(lv_classes) / sizeof(lv_classes[0]);
/* `lv_theme` methods */
/* `lv_img` methods */
#ifdef BE_LV_WIDGET_IMG
int be_ntv_lv_img_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_img_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_img_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_img_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_IMG
/* `lv_disp` methods */
/* `lv_obj` methods */
int be_ntv_lv_obj_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_obj_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_obj_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_obj_create, "+_p", "(lv.lv_obj)"); }
/* `lv_group` methods */
int be_ntv_lv_group_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_group_create, "+", ""); }
int be_ntv_lv_group_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_group_create, "+_p", ""); }
/* `lv_indev` methods */
/* `lv_chart` methods */
#ifdef BE_LV_WIDGET_CHART
int be_ntv_lv_chart_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_chart_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_chart_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_chart_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_CHART
/* `lv_colorwheel` methods */
#ifdef BE_LV_WIDGET_COLORWHEEL
int be_ntv_lv_colorwheel_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_colorwheel_create, "+", "(lv.lv_obj)b"); }
int be_ntv_lv_colorwheel_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_colorwheel_create, "+_p", "(lv.lv_obj)b"); }
#endif // BE_LV_WIDGET_COLORWHEEL
/* `lv_imgbtn` methods */
#ifdef BE_LV_WIDGET_IMGBTN
int be_ntv_lv_imgbtn_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_imgbtn_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_imgbtn_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_imgbtn_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_IMGBTN
/* `lv_led` methods */
#ifdef BE_LV_WIDGET_LED
int be_ntv_lv_led_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_led_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_led_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_led_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_LED
/* `lv_meter` methods */
#ifdef BE_LV_WIDGET_METER
int be_ntv_lv_meter_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_meter_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_meter_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_meter_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_METER
/* `lv_msgbox` methods */
#ifdef BE_LV_WIDGET_MSGBOX
int be_ntv_lv_msgbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_msgbox_create, "+", "(lv.lv_obj)sssb"); }
int be_ntv_lv_msgbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_msgbox_create, "+_p", "(lv.lv_obj)sssb"); }
#endif // BE_LV_WIDGET_MSGBOX
/* `lv_spinbox` methods */
#ifdef BE_LV_WIDGET_SPINBOX
int be_ntv_lv_spinbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_spinbox_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_spinbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_spinbox_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_SPINBOX
/* `lv_spinner` methods */
#ifdef BE_LV_WIDGET_SPINNER
int be_ntv_lv_spinner_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_spinner_create, "+", "(lv.lv_obj)ii"); }
int be_ntv_lv_spinner_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_spinner_create, "+_p", "(lv.lv_obj)ii"); }
#endif // BE_LV_WIDGET_SPINNER
/* `lv_arc` methods */
#ifdef BE_LV_WIDGET_ARC
int be_ntv_lv_arc_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_arc_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_arc_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_arc_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_ARC
/* `lv_bar` methods */
#ifdef BE_LV_WIDGET_BAR
int be_ntv_lv_bar_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_bar_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_bar_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_bar_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_BAR
/* `lv_btn` methods */
#ifdef BE_LV_WIDGET_BTN
int be_ntv_lv_btn_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_btn_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_btn_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_btn_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_BTN
/* `lv_btnmatrix` methods */
#ifdef BE_LV_WIDGET_BTNMATRIX
int be_ntv_lv_btnmatrix_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_btnmatrix_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_btnmatrix_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_btnmatrix_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_BTNMATRIX
/* `lv_canvas` methods */
#ifdef BE_LV_WIDGET_CANVAS
int be_ntv_lv_canvas_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_canvas_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_canvas_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_canvas_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_CANVAS
/* `lv_checkbox` methods */
#ifdef BE_LV_WIDGET_CHECKBOX
int be_ntv_lv_checkbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_checkbox_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_checkbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_checkbox_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_CHECKBOX
/* `lv_dropdown` methods */
#ifdef BE_LV_WIDGET_DROPDOWN
int be_ntv_lv_dropdown_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_dropdown_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_dropdown_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_dropdown_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_DROPDOWN
/* `lv_label` methods */
#ifdef BE_LV_WIDGET_LABEL
int be_ntv_lv_label_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_label_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_label_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_label_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_LABEL
/* `lv_line` methods */
#ifdef BE_LV_WIDGET_LINE
int be_ntv_lv_line_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_line_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_line_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_line_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_LINE
/* `lv_roller` methods */
#ifdef BE_LV_WIDGET_ROLLER
int be_ntv_lv_roller_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_roller_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_roller_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_roller_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_ROLLER
/* `lv_slider` methods */
#ifdef BE_LV_WIDGET_SLIDER
int be_ntv_lv_slider_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_slider_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_slider_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_slider_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_SLIDER
/* `lv_switch` methods */
#ifdef BE_LV_WIDGET_SWITCH
int be_ntv_lv_switch_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_switch_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_switch_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_switch_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_SWITCH
/* `lv_table` methods */
#ifdef BE_LV_WIDGET_TABLE
int be_ntv_lv_table_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_table_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_table_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_table_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_TABLE
/* `lv_textarea` methods */
#ifdef BE_LV_WIDGET_TEXTAREA
int be_ntv_lv_textarea_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_textarea_create, "+", "(lv.lv_obj)"); }
int be_ntv_lv_textarea_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_textarea_create, "+_p", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_TEXTAREA
// create font either empty or from parameter on stack
int lvbe_font_create(bvm *vm) { return be_call_c_func(vm, NULL, "+lv_font", ""); }
int lvbe_theme_create(bvm *vm) { return be_call_c_func(vm, NULL, "+lv_theme", ""); }
int lvbe_font_create(bvm *vm) { return be_call_c_func(vm, NULL, "+_p", ""); }
int lvbe_theme_create(bvm *vm) { return be_call_c_func(vm, NULL, "+_p", ""); }
#ifdef __cplusplus

View File

@ -6,10 +6,8 @@
*******************************************************************/
#include "be_constobj.h"
#ifdef USE_LVGL
#include "lvgl.h"
#include "be_lvgl.h"
#include "be_mapping.h"
#include "lv_theme_openhasp.h"
extern int lv0_member(bvm *vm); // resolve virtual members
@ -34,7 +32,7 @@ static int lv_get_ver_res(void) {
}
/* `lv` methods */
const lvbe_call_c_t lv_func[] = {
const be_ntv_func_def_t lv_func[] = {
{ "clamp_height", (void*) &lv_clamp_height, "i", "iiii" },
{ "clamp_width", (void*) &lv_clamp_width, "i", "iiii" },
@ -111,12 +109,7 @@ const size_t lv_func_size = sizeof(lv_func) / sizeof(lv_func[0]);
typedef struct be_constint_t {
const char * name;
int32_t value;
} be_constint_t;
const be_constint_t lv0_constants[] = {
const be_const_member_t lv0_constants[] = {
{ "ALIGN_BOTTOM_LEFT", LV_ALIGN_BOTTOM_LEFT },
{ "ALIGN_BOTTOM_MID", LV_ALIGN_BOTTOM_MID },
@ -687,6 +680,4 @@ be_local_module(lv,
);
BE_EXPORT_VARIABLE be_define_const_native_module(lv);
#endif // USE_LVGL
/********************************************************************/

View File

@ -8,8 +8,6 @@
*******************************************************************/
#include "be_constobj.h"
#ifdef USE_LVGL
#include "lvgl.h"
extern int lv0_init(bvm *vm);
@ -18,11 +16,11 @@ extern int lco_init(bvm *vm); // generic function
extern int lco_tostring(bvm *vm); // generic function
extern int lco_toint(bvm *vm); // generic function
extern int lvx_member(bvm *vm);
extern int lvx_tostring(bvm *vm); // generic function
extern int lv_x_member(bvm *vm);
extern int lv_x_tostring(bvm *vm); // generic function
extern int lvs_init(bvm *vm);
extern int lvs_tostring(bvm *vm);
extern int lv_x_tostring(bvm *vm);
BE_EXPORT_VARIABLE extern const bclass be_class_lv_obj;
@ -879,9 +877,9 @@ be_local_class(lv_style,
be_nested_map(4,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("init", 380752755, 4, -1), be_const_func(lvs_init) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lvs_tostring) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lv_x_tostring) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lvx_member) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lv_x_member) },
})),
(be_nested_const_str("lv_style", -143355747, 8))
);
@ -895,8 +893,8 @@ be_local_class(lv_obj,
NULL,
be_nested_map(5,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("tostring", -1995258651, 8, 3), be_const_func(lvx_tostring) },
{ be_nested_key("member", 719708611, 6, -1), be_const_func(lvx_member) },
{ be_nested_key("tostring", -1995258651, 8, 3), be_const_func(lv_x_tostring) },
{ be_nested_key("member", 719708611, 6, -1), be_const_func(lv_x_member) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
{ be_nested_key("init", 380752755, 4, 4), be_const_func(be_ntv_lv_obj_init) },
{ be_nested_key("_class", -1562820946, 6, -1), be_const_comptr(&lv_obj_class) },
@ -914,9 +912,9 @@ be_local_class(lv_group,
be_nested_map(4,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("init", 380752755, 4, -1), be_const_func(be_ntv_lv_group_init) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lvx_tostring) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lv_x_tostring) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lvx_member) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lv_x_member) },
})),
(be_nested_const_str("lv_group", -442928277, 8))
);
@ -931,9 +929,9 @@ be_local_class(lv_indev,
be_nested_map(4,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("init", 380752755, 4, -1), be_const_func(lv0_init) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lvx_tostring) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lv_x_tostring) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lvx_member) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lv_x_member) },
})),
(be_nested_const_str("lv_indev", 225602374, 8))
);
@ -948,9 +946,9 @@ be_local_class(lv_disp,
be_nested_map(4,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("init", 380752755, 4, -1), be_const_func(lv0_init) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lvx_tostring) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lv_x_tostring) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lvx_member) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lv_x_member) },
})),
(be_nested_const_str("lv_disp", 609712084, 8))
);
@ -965,7 +963,7 @@ be_local_class(lv_font,
be_nested_map(3,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("init", 380752755, 4, -1), be_const_func(lvbe_font_create) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lvx_tostring) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lv_x_tostring) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
})),
(be_nested_const_str("lv_font", 1550958453, 7))
@ -981,7 +979,7 @@ be_local_class(lv_theme,
be_nested_map(3,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("init", 380752755, 4, -1), be_const_func(lvbe_theme_create) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lvx_tostring) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lv_x_tostring) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
})),
(be_nested_const_str("lv_theme", 1550958453, 7))
@ -1559,6 +1557,3 @@ void be_load_lv_textarea_class(bvm *vm) {
be_pop(vm, 1);
}
#endif // USE_LVGL

View File

@ -0,0 +1,25 @@
{
"name": "Berry mapping to LVGL",
"version": "1.0",
"description": "Mapping of LVGL functions to Berry",
"license": "MIT",
"homepage": "https://github.com/arendst/Tasmota",
"frameworks": "*",
"platforms": "*",
"authors":
{
"name": "Stephan Hadinger",
"maintainer": true
},
"build": {
"srcFilter": [
"+<*.c>",
"+<../generate/*.c>",
"+<../generate/*.cpp>",
"+<../generate/*.hpp>",
"+<*.cpp>",
"+<*.h>"
],
"flags": [ "-I$PROJECT_DIR/include", "-includetasmota_options.h" ]
}
}

View File

@ -28,7 +28,7 @@ lv_coord_t lv_get_ver_res(void);
// ======================================================================
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_disp.h
// ../../lvgl/src/core/lv_disp.h
lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp)
lv_obj_t * lv_disp_get_scr_prev(lv_disp_t * disp)
void lv_disp_load_scr(lv_obj_t * scr)
@ -50,7 +50,7 @@ static inline void lv_scr_load(lv_obj_t * scr)
static inline lv_coord_t lv_dpx(lv_coord_t n)
static inline lv_coord_t lv_disp_dpx(const lv_disp_t * disp, lv_coord_t n)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_event.h
// ../../lvgl/src/core/lv_event.h
lv_res_t lv_event_send(struct _lv_obj_t * obj, lv_event_code_t event_code, void * param)
lv_res_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e)
uint32_t lv_event_register_id(void)
@ -60,7 +60,7 @@ bool lv_obj_remove_event_dsc(struct _lv_obj_t * obj, struct _lv_event_dsc_t * ev
void lv_event_set_ext_draw_size(lv_event_t * e, lv_coord_t size)
void lv_event_set_cover_res(lv_event_t * e, lv_cover_res_t res)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_group.h
// ../../lvgl/src/core/lv_group.h
lv_group_t * lv_group_create(void)
void lv_group_del(lv_group_t * group)
void lv_group_set_default(lv_group_t * group)
@ -83,7 +83,7 @@ bool lv_group_get_editing(const lv_group_t * group)
bool lv_group_get_wrap(lv_group_t * group)
uint32_t lv_group_get_obj_count(lv_group_t * group)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_indev.h
// ../../lvgl/src/core/lv_indev.h
void lv_indev_read_timer_cb(lv_timer_t * timer)
void lv_indev_enable(lv_indev_t * indev, bool en)
lv_indev_t * lv_indev_get_act(void)
@ -104,9 +104,9 @@ lv_obj_t * lv_indev_get_obj_act(void)
lv_timer_t * lv_indev_get_read_timer(lv_disp_t * indev)
lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_indev_scroll.h
// ../../lvgl/src/core/lv_indev_scroll.h
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_obj.h
// ../../lvgl/src/core/lv_obj.h
lv_obj_t * lv_obj_create(lv_obj_t * parent)
void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f)
void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f)
@ -126,13 +126,13 @@ const lv_obj_class_t * lv_obj_get_class(const lv_obj_t * obj)
bool lv_obj_is_valid(const lv_obj_t * obj)
static inline lv_coord_t lv_obj_dpx(const lv_obj_t * obj, lv_coord_t n)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_obj_class.h
// ../../lvgl/src/core/lv_obj_class.h
struct _lv_obj_t * lv_obj_class_create_obj(const struct _lv_obj_class_t * class_p, struct _lv_obj_t * parent)
void lv_obj_class_init_obj(struct _lv_obj_t * obj)
bool lv_obj_is_editable(struct _lv_obj_t * obj)
bool lv_obj_is_group_def(struct _lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_obj_draw.h
// ../../lvgl/src/core/lv_obj_draw.h
void lv_obj_init_draw_rect_dsc(struct _lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t * draw_dsc)
void lv_obj_init_draw_label_dsc(struct _lv_obj_t * obj, uint32_t part, lv_draw_label_dsc_t * draw_dsc)
void lv_obj_init_draw_img_dsc(struct _lv_obj_t * obj, uint32_t part, lv_draw_img_dsc_t * draw_dsc)
@ -142,7 +142,7 @@ lv_coord_t lv_obj_calculate_ext_draw_size(struct _lv_obj_t * obj, uint32_t part)
void lv_obj_draw_dsc_init(lv_obj_draw_part_dsc_t * dsc, const lv_area_t * clip_area)
void lv_obj_refresh_ext_draw_size(struct _lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_obj_pos.h
// ../../lvgl/src/core/lv_obj_pos.h
void lv_obj_set_pos(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
void lv_obj_set_x(struct _lv_obj_t * obj, lv_coord_t x)
void lv_obj_set_y(struct _lv_obj_t * obj, lv_coord_t y)
@ -187,7 +187,7 @@ bool lv_obj_hit_test(struct _lv_obj_t * obj, const lv_point_t * point)
lv_coord_t lv_clamp_width(lv_coord_t width, lv_coord_t min_width, lv_coord_t max_width, lv_coord_t ref_width)
lv_coord_t lv_clamp_height(lv_coord_t height, lv_coord_t min_height, lv_coord_t max_height, lv_coord_t ref_height)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_obj_scroll.h
// ../../lvgl/src/core/lv_obj_scroll.h
void lv_obj_set_scrollbar_mode(struct _lv_obj_t * obj, lv_scrollbar_mode_t mode)
void lv_obj_set_scroll_dir(struct _lv_obj_t * obj, lv_dir_t dir)
void lv_obj_set_scroll_snap_x(struct _lv_obj_t * obj, lv_scroll_snap_t align)
@ -215,7 +215,7 @@ void lv_obj_get_scrollbar_area(struct _lv_obj_t * obj, lv_area_t * hor, lv_area_
void lv_obj_scrollbar_invalidate(struct _lv_obj_t * obj)
void lv_obj_readjust_scroll(struct _lv_obj_t * obj, lv_anim_enable_t anim_en)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_obj_style.h
// ../../lvgl/src/core/lv_obj_style.h
void lv_obj_add_style(struct _lv_obj_t * obj, lv_style_t * style, lv_style_selector_t selector)
void lv_obj_remove_style(struct _lv_obj_t * obj, lv_style_t * style, lv_style_selector_t selector)
static inline void lv_obj_remove_style_all(struct _lv_obj_t * obj)
@ -236,7 +236,7 @@ static inline void lv_obj_set_style_pad_ver(struct _lv_obj_t * obj, lv_coord_t v
static inline void lv_obj_set_style_pad_gap(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
static inline void lv_obj_set_style_size(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_obj_style_gen.h
// ../../lvgl/src/core/lv_obj_style_gen.h
static inline lv_coord_t lv_obj_get_style_width(const struct _lv_obj_t * obj, uint32_t part)
static inline lv_coord_t lv_obj_get_style_min_width(const struct _lv_obj_t * obj, uint32_t part)
static inline lv_coord_t lv_obj_get_style_max_width(const struct _lv_obj_t * obj, uint32_t part)
@ -416,7 +416,7 @@ void lv_obj_set_style_arc_color_filtered(struct _lv_obj_t * obj, lv_color_t valu
void lv_obj_set_style_arc_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
void lv_obj_set_style_arc_img_src(struct _lv_obj_t * obj, const void * value, lv_style_selector_t selector)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_obj_tree.h
// ../../lvgl/src/core/lv_obj_tree.h
void lv_obj_del(struct _lv_obj_t * obj)
void lv_obj_clean(struct _lv_obj_t * obj)
void lv_obj_del_anim_ready_cb(lv_anim_t * a)
@ -432,10 +432,10 @@ uint32_t lv_obj_get_child_cnt(const struct _lv_obj_t * obj)
uint32_t lv_obj_get_child_id(const struct _lv_obj_t * obj)
void lv_obj_tree_walk(struct _lv_obj_t * start_obj, lv_obj_tree_walk_cb_t cb, void * user_data)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_refr.h
// ../../lvgl/src/core/lv_refr.h
void lv_refr_now(lv_disp_t * disp)
// ../../lib/libesp32_lvgl/LVGL8/src/core/lv_theme.h
// ../../lvgl/src/core/lv_theme.h
lv_theme_t * lv_theme_get_from_obj(lv_obj_t * obj)
void lv_theme_apply(lv_obj_t * obj)
void lv_theme_set_parent(lv_theme_t * new_theme, lv_theme_t * parent)
@ -446,30 +446,30 @@ const lv_font_t * lv_theme_get_font_large(lv_obj_t * obj)
lv_color_t lv_theme_get_color_primary(lv_obj_t * obj)
lv_color_t lv_theme_get_color_secondary(lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/draw/lv_draw.h
// ../../lvgl/src/draw/lv_draw.h
// ../../lib/libesp32_lvgl/LVGL8/src/draw/lv_draw_arc.h
// ../../lvgl/src/draw/lv_draw_arc.h
void lv_draw_arc_dsc_init(lv_draw_arc_dsc_t * dsc)
void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uint16_t start_angle, uint16_t end_angle, const lv_area_t * clip_area, const lv_draw_arc_dsc_t * dsc)
void lv_draw_arc_get_area(lv_coord_t x, lv_coord_t y, uint16_t radius, uint16_t start_angle, uint16_t end_angle, lv_coord_t w, bool rounded, lv_area_t * area)
// ../../lib/libesp32_lvgl/LVGL8/src/draw/lv_draw_blend.h
// ../../lvgl/src/draw/lv_draw_blend.h
// ../../lib/libesp32_lvgl/LVGL8/src/draw/lv_draw_img.h
// ../../lvgl/src/draw/lv_draw_img.h
void lv_draw_img_dsc_init(lv_draw_img_dsc_t * dsc)
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_draw_img_dsc_t * dsc)
lv_img_src_t lv_img_src_get_type(const void * src)
// ../../lib/libesp32_lvgl/LVGL8/src/draw/lv_draw_label.h
// ../../lvgl/src/draw/lv_draw_label.h
void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc)
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_draw_label_dsc_t * dsc, const char * txt, lv_draw_label_hint_t * hint)
void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area, const lv_font_t * font_p, uint32_t letter, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode)
// ../../lib/libesp32_lvgl/LVGL8/src/draw/lv_draw_line.h
// ../../lvgl/src/draw/lv_draw_line.h
void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, const lv_draw_line_dsc_t * dsc)
void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc)
// ../../lib/libesp32_lvgl/LVGL8/src/draw/lv_draw_mask.h
// ../../lvgl/src/draw/lv_draw_mask.h
static inline uint8_t lv_draw_mask_get_cnt(void)
int16_t lv_draw_mask_add(void * param, void * custom_id)
lv_draw_mask_res_t lv_draw_mask_apply(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len)
@ -483,28 +483,28 @@ void lv_draw_mask_radius_init(lv_draw_mask_radius_param_t * param, const lv_area
void lv_draw_mask_fade_init(lv_draw_mask_fade_param_t * param, const lv_area_t * coords, lv_opa_t opa_top, lv_coord_t y_top, lv_opa_t opa_bottom, lv_coord_t y_bottom)
void lv_draw_mask_map_init(lv_draw_mask_map_param_t * param, const lv_area_t * coords, const lv_opa_t * map)
// ../../lib/libesp32_lvgl/LVGL8/src/draw/lv_draw_rect.h
// ../../lvgl/src/draw/lv_draw_rect.h
void lv_draw_rect_dsc_init(lv_draw_rect_dsc_t * dsc)
void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_draw_rect_dsc_t * dsc)
// ../../lib/libesp32_lvgl/LVGL8/src/draw/lv_draw_triangle.h
// ../../lvgl/src/draw/lv_draw_triangle.h
void lv_draw_triangle(const lv_point_t points[], const lv_area_t * clip, const lv_draw_rect_dsc_t * draw_dsc)
void lv_draw_polygon(const lv_point_t points[], uint16_t point_cnt, const lv_area_t * mask, const lv_draw_rect_dsc_t * draw_dsc)
// ../../lib/libesp32_lvgl/LVGL8/src/draw/lv_img_buf.h
// ../../lvgl/src/draw/lv_img_buf.h
// ../../lib/libesp32_lvgl/LVGL8/src/draw/lv_img_cache.h
// ../../lvgl/src/draw/lv_img_cache.h
// ../../lib/libesp32_lvgl/LVGL8/src/draw/lv_img_decoder.h
// ../../lvgl/src/draw/lv_img_decoder.h
// ../../lib/libesp32_lvgl/LVGL8/src/extra/themes/default/lv_theme_default.h
// ../../lvgl/src/extra/themes/default/lv_theme_default.h
lv_theme_t * lv_theme_default_init(lv_disp_t * disp, lv_color_t color_primary, lv_color_t color_secondary, bool dark, const lv_font_t * font)
bool lv_theme_default_is_inited(void)
// ../../lib/libesp32_lvgl/LVGL8/src/extra/themes/mono/lv_theme_mono.h
// ../../lvgl/src/extra/themes/mono/lv_theme_mono.h
lv_theme_t * lv_theme_mono_init(lv_disp_t * disp, bool dark_bg, const lv_font_t * font)
// ../../lib/libesp32_lvgl/LVGL8/src/extra/widgets/chart/lv_chart.h
// ../../lvgl/src/extra/widgets/chart/lv_chart.h
lv_obj_t * lv_chart_create(lv_obj_t * parent)
void lv_chart_set_type(lv_obj_t * obj, lv_chart_type_t type)
void lv_chart_set_point_count(lv_obj_t * obj, uint16_t cnt)
@ -542,7 +542,7 @@ lv_coord_t * lv_chart_get_y_array(const lv_obj_t * obj, lv_chart_series_t * ser)
lv_coord_t * lv_chart_get_x_array(const lv_obj_t * obj, lv_chart_series_t * ser)
uint32_t lv_chart_get_pressed_point(const lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/extra/widgets/colorwheel/lv_colorwheel.h
// ../../lvgl/src/extra/widgets/colorwheel/lv_colorwheel.h
lv_obj_t * lv_colorwheel_create(lv_obj_t * parent, bool knob_recolor)
bool lv_colorwheel_set_hsv(lv_obj_t * obj, lv_color_hsv_t hsv)
bool lv_colorwheel_set_rgb(lv_obj_t * obj, lv_color_t color)
@ -553,11 +553,11 @@ lv_color_t lv_colorwheel_get_rgb(lv_obj_t * obj)
lv_colorwheel_mode_t lv_colorwheel_get_color_mode(lv_obj_t * obj)
bool lv_colorwheel_get_color_mode_fixed(lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/extra/widgets/imgbtn/lv_imgbtn.h
// ../../lvgl/src/extra/widgets/imgbtn/lv_imgbtn.h
lv_obj_t * lv_imgbtn_create(lv_obj_t * parent)
void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_imgbtn_state_t state, const void * src_left, const void * src_mid, const void * src_right)
// ../../lib/libesp32_lvgl/LVGL8/src/extra/widgets/led/lv_led.h
// ../../lvgl/src/extra/widgets/led/lv_led.h
lv_obj_t * lv_led_create(lv_obj_t * parent)
void lv_led_set_color(lv_obj_t * led, lv_color_t color)
void lv_led_set_brightness(lv_obj_t * led, uint8_t bright)
@ -566,7 +566,7 @@ void lv_led_off(lv_obj_t * led)
void lv_led_toggle(lv_obj_t * led)
uint8_t lv_led_get_brightness(const lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/extra/widgets/meter/lv_meter.h
// ../../lvgl/src/extra/widgets/meter/lv_meter.h
lv_obj_t * lv_meter_create(lv_obj_t * parent)
lv_meter_scale_t * lv_meter_add_scale(lv_obj_t * obj)
void lv_meter_set_scale_ticks(lv_obj_t * obj, lv_meter_scale_t * scale, uint16_t cnt, uint16_t width, uint16_t len, lv_color_t color)
@ -580,7 +580,7 @@ void lv_meter_set_indicator_value(lv_obj_t * obj, lv_meter_indicator_t * indic,
void lv_meter_set_indicator_start_value(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t value)
void lv_meter_set_indicator_end_value(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t value)
// ../../lib/libesp32_lvgl/LVGL8/src/extra/widgets/msgbox/lv_msgbox.h
// ../../lvgl/src/extra/widgets/msgbox/lv_msgbox.h
lv_obj_t * lv_msgbox_create(lv_obj_t * parent, const char * title, const char * txt, const char * btn_txts[], bool add_close_btn)
lv_obj_t * lv_msgbox_get_title(lv_obj_t * mbox)
lv_obj_t * lv_msgbox_get_close_btn(lv_obj_t * mbox)
@ -589,7 +589,7 @@ lv_obj_t * lv_msgbox_get_btns(lv_obj_t * mbox)
const char * lv_msgbox_get_active_btn_text(lv_obj_t * mbox)
void lv_msgbox_close(lv_obj_t * mbox)
// ../../lib/libesp32_lvgl/LVGL8/src/extra/widgets/spinbox/lv_spinbox.h
// ../../lvgl/src/extra/widgets/spinbox/lv_spinbox.h
lv_obj_t * lv_spinbox_create(lv_obj_t * parent)
void lv_spinbox_set_value(lv_obj_t * obj, int32_t i)
void lv_spinbox_set_rollover(lv_obj_t * obj, bool b)
@ -604,10 +604,10 @@ void lv_spinbox_step_prev(lv_obj_t * obj)
void lv_spinbox_increment(lv_obj_t * obj)
void lv_spinbox_decrement(lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/extra/widgets/spinner/lv_spinner.h
// ../../lvgl/src/extra/widgets/spinner/lv_spinner.h
lv_obj_t * lv_spinner_create(lv_obj_t * parent, uint32_t time, uint32_t arc_length)
// ../../lib/libesp32_lvgl/LVGL8/src/misc/lv_style_gen.h
// ../../lvgl/src/misc/lv_style_gen.h
void lv_style_set_width(lv_style_t * style, lv_coord_t value)
void lv_style_set_min_width(lv_style_t * style, lv_coord_t value)
void lv_style_set_max_width(lv_style_t * style, lv_coord_t value)
@ -698,7 +698,7 @@ void lv_style_set_arc_color_filtered(lv_style_t * style, lv_color_t value)
void lv_style_set_arc_opa(lv_style_t * style, lv_opa_t value)
void lv_style_set_arc_img_src(lv_style_t * style, const void * value)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_arc.h
// ../../lvgl/src/widgets/lv_arc.h
lv_obj_t * lv_arc_create(lv_obj_t * parent)
void lv_arc_set_start_angle(lv_obj_t * arc, uint16_t start)
void lv_arc_set_end_angle(lv_obj_t * arc, uint16_t end)
@ -720,7 +720,7 @@ int16_t lv_arc_get_min_value(const lv_obj_t * obj)
int16_t lv_arc_get_max_value(const lv_obj_t * obj)
lv_arc_mode_t lv_arc_get_mode(const lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_bar.h
// ../../lvgl/src/widgets/lv_bar.h
lv_obj_t * lv_bar_create(lv_obj_t * parent)
void lv_bar_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim)
void lv_bar_set_start_value(lv_obj_t * obj, int32_t start_value, lv_anim_enable_t anim)
@ -732,10 +732,10 @@ int32_t lv_bar_get_min_value(const lv_obj_t * obj)
int32_t lv_bar_get_max_value(const lv_obj_t * obj)
lv_bar_mode_t lv_bar_get_mode(lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_btn.h
// ../../lvgl/src/widgets/lv_btn.h
lv_obj_t * lv_btn_create(lv_obj_t * parent)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_btnmatrix.h
// ../../lvgl/src/widgets/lv_btnmatrix.h
lv_obj_t * lv_btnmatrix_create(lv_obj_t * parent)
void lv_btnmatrix_set_map(lv_obj_t * obj, const char * map[])
void lv_btnmatrix_set_ctrl_map(lv_obj_t * obj, const lv_btnmatrix_ctrl_t ctrl_map[])
@ -752,7 +752,7 @@ const char * lv_btnmatrix_get_btn_text(const lv_obj_t * obj, uint16_t btn_id)
bool lv_btnmatrix_has_btn_ctrl(lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl)
bool lv_btnmatrix_get_one_checked(const lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_canvas.h
// ../../lvgl/src/widgets/lv_canvas.h
lv_obj_t * lv_canvas_create(lv_obj_t * parent)
void lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
void lv_canvas_set_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t c)
@ -771,13 +771,13 @@ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t
void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, const lv_draw_rect_dsc_t * draw_dsc)
void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t r, int32_t start_angle, int32_t end_angle, const lv_draw_arc_dsc_t * draw_dsc)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_checkbox.h
// ../../lvgl/src/widgets/lv_checkbox.h
lv_obj_t * lv_checkbox_create(lv_obj_t * parent)
void lv_checkbox_set_text(lv_obj_t * obj, const char * txt)
void lv_checkbox_set_text_static(lv_obj_t * obj, const char * txt)
const char * lv_checkbox_get_text(const lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_dropdown.h
// ../../lvgl/src/widgets/lv_dropdown.h
lv_obj_t * lv_dropdown_create(lv_obj_t * parent)
void lv_dropdown_set_text(lv_obj_t * obj, const char * txt)
void lv_dropdown_set_options(lv_obj_t * obj, const char * options)
@ -800,7 +800,7 @@ lv_dir_t lv_dropdown_get_dir(const lv_obj_t * obj)
void lv_dropdown_open(lv_obj_t * dropdown_obj)
void lv_dropdown_close(lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_img.h
// ../../lvgl/src/widgets/lv_img.h
lv_obj_t * lv_img_create(lv_obj_t * parent)
void lv_img_set_src(lv_obj_t * obj, const void * src)
void lv_img_set_offset_x(lv_obj_t * obj, lv_coord_t x)
@ -817,7 +817,7 @@ void lv_img_get_pivot(lv_obj_t * obj, lv_point_t * pivot)
uint16_t lv_img_get_zoom(lv_obj_t * obj)
bool lv_img_get_antialias(lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_label.h
// ../../lvgl/src/widgets/lv_label.h
lv_obj_t * lv_label_create(lv_obj_t * parent)
void lv_label_set_text(lv_obj_t * obj, const char * text)
void lv_label_set_text_fmt(lv_obj_t * obj, const char * fmt, ...) LV_FORMAT_ATTRIBUTE(2, 3)
@ -837,15 +837,15 @@ uint32_t lv_label_get_text_selection_end(const lv_obj_t * obj)
void lv_label_ins_text(lv_obj_t * obj, uint32_t pos, const char * txt)
void lv_label_cut_text(lv_obj_t * obj, uint32_t pos, uint32_t cnt)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_line.h
// ../../lvgl/src/widgets/lv_line.h
lv_obj_t * lv_line_create(lv_obj_t * parent)
void lv_line_set_points(lv_obj_t * obj, const lv_point_t points[], uint16_t point_num)
void lv_line_set_y_invert(lv_obj_t * obj, bool en)
bool lv_line_get_y_invert(const lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_objx_templ.h
// ../../lvgl/src/widgets/lv_objx_templ.h
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_roller.h
// ../../lvgl/src/widgets/lv_roller.h
lv_obj_t * lv_roller_create(lv_obj_t * parent)
void lv_roller_set_options(lv_obj_t * obj, const char * options, lv_roller_mode_t mode)
void lv_roller_set_selected(lv_obj_t * obj, uint16_t sel_opt, lv_anim_enable_t anim)
@ -855,7 +855,7 @@ void lv_roller_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf_s
const char * lv_roller_get_options(const lv_obj_t * obj)
uint16_t lv_roller_get_option_cnt(const lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_slider.h
// ../../lvgl/src/widgets/lv_slider.h
lv_obj_t * lv_slider_create(lv_obj_t * parent)
static inline void lv_slider_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim)
static inline void lv_slider_set_left_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim)
@ -868,10 +868,10 @@ static inline int32_t lv_slider_get_max_value(const lv_obj_t * obj)
bool lv_slider_is_dragged(const lv_obj_t * obj)
static inline lv_slider_mode_t lv_slider_get_mode(lv_obj_t * slider)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_switch.h
// ../../lvgl/src/widgets/lv_switch.h
lv_obj_t * lv_switch_create(lv_obj_t * parent)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_table.h
// ../../lvgl/src/widgets/lv_table.h
lv_obj_t * lv_table_create(lv_obj_t * parent)
void lv_table_set_cell_value(lv_obj_t * obj, uint16_t row, uint16_t col, const char * txt)
void lv_table_set_cell_value_fmt(lv_obj_t * obj, uint16_t row, uint16_t col, const char * fmt, ...)
@ -887,7 +887,7 @@ lv_coord_t lv_table_get_col_width(lv_obj_t * obj, uint16_t col)
bool lv_table_has_cell_ctrl(lv_obj_t * obj, uint16_t row, uint16_t col, lv_table_cell_ctrl_t ctrl)
void lv_table_get_selected_cell(lv_obj_t * obj, uint16_t * row, uint16_t * col)
// ../../lib/libesp32_lvgl/LVGL8/src/widgets/lv_textarea.h
// ../../lvgl/src/widgets/lv_textarea.h
lv_obj_t * lv_textarea_create(lv_obj_t * parent)
void lv_textarea_add_char(lv_obj_t * obj, uint32_t c)
void lv_textarea_add_text(lv_obj_t * obj, const char * txt)
@ -923,7 +923,7 @@ void lv_textarea_cursor_left(lv_obj_t * obj)
void lv_textarea_cursor_down(lv_obj_t * obj)
void lv_textarea_cursor_up(lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL_assets/src/lv_theme_openhasp.h
// ../../LVGL_assets/src/lv_theme_openhasp.h
lv_theme_t * lv_theme_openhasp_init(lv_disp_t * disp, lv_color_t color_primary, lv_color_t color_secondary, bool dark, const lv_font_t * font)
bool lv_theme_openhasp_is_inited(void)

View File

@ -3,10 +3,8 @@
*******************************************************************/
#include "be_ctypes.h"
#ifdef USE_LVGL
#include "lvgl.h"
#include "be_lvgl.h"
#include "be_mapping.h"
/********************************************************************
* Generated code, don't edit
@ -527,5 +525,3 @@ be_ctypes_class_by_name_t be_ctypes_lvgl_classes[] = {
const size_t be_ctypes_lvgl_classes_size = sizeof(be_ctypes_lvgl_classes)/sizeof(be_ctypes_lvgl_classes[0]);
/********************************************************************/
#endif // USE_LVGL

View File

@ -20,6 +20,12 @@ class LVGL_glob
#- this is the fallback callback, if the event is unknown or unsupported -#
static cb_do_nothing = def() print("LVG: call to unsupported callback") end
# register our callback handler to `module cb`
def init()
import cb
cb.add_handler(/ f, obj, name -> self.make_cb(f, obj, name))
end
#- register an lv.lv_* object in the mapping -#
def register_obj(obj)
if self.cb_obj == nil self.cb_obj = {} end
@ -44,21 +50,24 @@ class LVGL_glob
f(obj, event)
end
def gen_cb(name, f, obj, ptr)
#print('>> gen_cb', name, obj, ptr)
def make_cb(f, obj, name)
import cb
# print('>> make_cb', f, name, obj)
# record the object, whatever the callback
if name == "lv_event_cb"
if self.cb_event_closure == nil self.cb_event_closure = {} end
if self.event_cb == nil self.event_cb = tasmota.gen_cb(/ event_ptr -> self.lvgl_event_dispatch(event_ptr)) end # encapsulate 'self' in closure
if self.event_cb == nil self.event_cb = cb.gen_cb(/ event_ptr -> self.lvgl_event_dispatch(event_ptr)) end # encapsulate 'self' in closure
self.register_obj(obj)
self.cb_event_closure[ptr] = f
self.cb_event_closure[obj._p] = f
return self.event_cb
# elif name == "<other_cb>"
else
if self.null_cb == nil self.null_cb = tasmota.gen_cb(self.cb_do_nothing) end
elif name[0..2] == "lv_"
if self.null_cb == nil self.null_cb = cb.gen_cb(self.cb_do_nothing) end
return self.null_cb
else
return nil # the call is not for us, pass to next handler
end
end
@ -95,9 +104,10 @@ class LVGL_glob
def widget_cb()
if self.widget_ctor_cb == nil self.widget_ctor_cb = tasmota.gen_cb(/ cl, obj -> self.widget_ctor_impl(cl, obj)) end
if self.widget_dtor_cb == nil self.widget_dtor_cb = tasmota.gen_cb(/ cl, obj -> self.widget_dtor_impl(cl, obj)) end
if self.widget_event_cb == nil self.widget_event_cb = tasmota.gen_cb(/ cl, e -> self.widget_event_impl(cl, e)) end
import cb
if self.widget_ctor_cb == nil self.widget_ctor_cb = cb.gen_cb(/ cl, obj -> self.widget_ctor_impl(cl, obj)) end
if self.widget_dtor_cb == nil self.widget_dtor_cb = cb.gen_cb(/ cl, obj -> self.widget_dtor_impl(cl, obj)) end
if self.widget_event_cb == nil self.widget_event_cb = cb.gen_cb(/ cl, e -> self.widget_event_impl(cl, e)) end
if self.widget_struct_default == nil
self.widget_struct_default = lv.lv_obj_class(lv.lv_obj._class).copy()

View File

@ -0,0 +1,298 @@
#include "lv_berry.h"
#include "be_mapping.h"
#include "be_exec.h"
#include "be_vm.h"
#include "be_mem.h"
#include <stdio.h>
#include "../generate/be_lv_c_mapping.h"
extern void be_load_lv_color_class(bvm *vm);
extern void be_load_lv_font_class(bvm *vm);
extern void be_load_LVGL_glob_class(bvm *vm);
void be_load_lvgl_classes(bvm *vm) {
be_load_lv_color_class(vm);
be_load_lv_font_class(vm);
be_load_LVGL_glob_class(vm);
}
/*********************************************************************************************\
* Support for lv
\*********************************************************************************************/
// Get the `_p` member of instance at `index`
void * lv_get_arg(bvm *vm, int index) {
void * ret = NULL;
if (be_isinstance(vm, index)) {
be_getmember(vm, index, "_p");
ret = be_tocomptr(vm, -1);
be_pop(vm, 1); // remove _p attribute
}
return ret;
}
/*********************************************************************************************\
* Support for lv_indev and objects that don't need creator
\*********************************************************************************************/
int lv0_init(bvm *vm);
int lv0_init(bvm *vm) {
// "+_p" indicates that there must be an non NULL argument, either passed as comptr or returned by the function
// Here, there is no function, so calling the constructor without a non-null comptr argument is rejected
return be_call_c_func(vm, NULL, "+_p", NULL);
}
/*********************************************************************************************\
* Generalized tostring method, shows class and _p value
\*********************************************************************************************/
int lv_x_tostring(bvm *vm) {
lv_obj_t * obj = (lv_obj_t*) lv_get_arg(vm, 1);
const char * classname = be_classname(vm, 1);
char s[48];
snprintf(s, sizeof(s), "<instance: %s(0x%08X)>", classname, obj);
be_pushnstring(vm, s, strlen(s)); /* make escape string from buffer */
be_return(vm);
}
/*********************************************************************************************\
* Support for lv_style
\*********************************************************************************************/
int lvs_init(bvm *vm) {
int argc = be_top(vm);
lv_style_t * style = NULL;
if (argc > 1) {
style = (lv_style_t*) be_convert_single_elt(vm, 2, NULL, NULL);
}
if (style == NULL) {
style = (lv_style_t*) be_malloc(vm, sizeof(lv_style_t));
if (style == NULL) {
be_throw(vm, BE_MALLOC_FAIL);
}
if (style != NULL) {
lv_style_init(style);
}
}
be_pushcomptr(vm, style);
be_setmember(vm, 1, "_p");
be_return_nil(vm);
}
// native closure to call `be_call_c_func`
int lv_x_call_c(bvm *vm) {
// berry_log_C("lv_x_call_c enter");
// keep parameters unchanged
be_getupval(vm, 0, 0); // if index is zero, it's the current native closure
void * func = be_tocomptr(vm, -1);
be_getupval(vm, 0, 1); // if index is zero, it's the current native closure
const char * return_type = be_tostring(vm, -1);
be_getupval(vm, 0, 2); // if index is zero, it's the current native closure
const char * arg_type = be_tostring(vm, -1);
be_pop(vm, 3); // remove 3 upvals
// berry_log_C("lv_x_call_c %p '%s' <- (%s)", func, return_type, arg_type);
return be_call_c_func(vm, func, return_type, arg_type);
}
// virtual method, arg1: instance, arg2: name of method
int lv_x_member(bvm *vm) {
int32_t argc = be_top(vm); // Get the number of arguments
if (argc == 2 && be_isinstance(vm, 1) && be_isstring(vm, 2)) {
const char * method_name = be_tostring(vm, 2); // the method we are looking for
while (be_isinstance(vm, 1)) {
const char * class_name = be_classname(vm, 1);
// berry_log_C("lv_x_member looking for method '%s' of class '%s'", method_name, class_name);
// look for class descriptor
int32_t class_idx = be_map_bin_search(class_name, &lv_classes[0].name, sizeof(lv_classes[0]), lv_classes_size);
if (class_idx >= 0) {
const be_ntv_func_def_t * methods_calls = lv_classes[class_idx].func_table;
size_t methods_size = lv_classes[class_idx].size;
int32_t method_idx = be_map_bin_search(method_name, methods_calls, sizeof(be_ntv_func_def_t), methods_size);
if (method_idx >= 0) {
// method found
const be_ntv_func_def_t * method = &methods_calls[method_idx];
// berry_log_C("lv_x_member method found func=%p return_type=%s arg_type=%s", method->func, method->return_type, method->arg_type);
// push native closure
be_pushntvclosure(vm, &lv_x_call_c, 3); // 3 upvals
be_pushcomptr(vm, method->func);
be_setupval(vm, -2, 0);
be_pop(vm, 1);
be_pushstring(vm, method->return_type);
be_setupval(vm, -2, 1);
be_pop(vm, 1);
be_pushstring(vm, method->arg_type);
be_setupval(vm, -2, 2);
be_pop(vm, 1);
// all good
be_return(vm);
}
}
// get super if any, or nil if none
be_getsuper(vm, 1);
be_moveto(vm, -1, 1);
be_pop(vm, 1);
}
// berry_log_C("lv_x_member method not found");
be_return_nil(vm);
}
be_raise(vm, "type_error", NULL);
}
// lv_color
// First arg is a 24 bits RGB color
// If first arg is `nil` second arg is the native value of color
int lco_init(bvm *vm) {
int argc = be_top(vm);
uint32_t color32 = 0x000000; // default to black
if (argc > 1) {
color32 = be_toint(vm, 2);
}
lv_color_t lv_color = lv_color_hex(color32);
if (argc > 2 && be_toint(vm, 3) == -1) {
lv_color.full = be_toint(vm, 2);
}
be_pushint(vm, lv_color_to_uint32(lv_color));
be_setmember(vm, 1, "_p");
be_return_nil(vm);
}
int lco_tostring(bvm *vm) {
lv_color_t lv_color = {};
be_getmember(vm, 1, "_p");
uint32_t ntv_color = be_toint(vm, -1);
lv_color = lv_color_from_uint32(ntv_color);
uint32_t color = lv_color_to32(lv_color) & 0xFFFFFF;
be_pop(vm, 1); // remove attribute
char s[48];
snprintf(s, sizeof(s), "lv_color(0x%06x - native:0x%04x)", color, ntv_color);
be_pushnstring(vm, s, strlen(s)); /* make escape string from buffer */
be_return(vm);
}
int lco_toint(bvm *vm) {
lv_color_t lv_color = {};
be_getmember(vm, 1, "_p");
uint32_t ntv_color = be_toint(vm, -1);
be_pushint(vm, ntv_color);
be_return(vm);
}
// function is (void) -> lv_obt_t*
typedef lv_obj_t* (*fn_lvobj__void)(void); // f() -> newly created lv_obj()
int lv0_lvobj__void_call(bvm *vm, fn_lvobj__void func) {
lv_obj_t * obj = (*func)();
be_find_global_or_module_member(vm, "lv.lv_obj");
be_pushcomptr(vm, (void*) -1); // stack = class, -1
be_pushcomptr(vm, (void*) obj); // stack = class, -1, ptr
be_call(vm, 2); // instanciate, stack = instance (don't call init() )
be_pop(vm, 2); // stack = instance
be_return(vm);
}
/*********************************************************************************************\
* Support for lv_fonts
\*********************************************************************************************/
// load font by name on file-system
int lv0_load_font(bvm *vm) {
int argc = be_top(vm);
if (argc == 1 && be_isstring(vm, 1)) {
lv_font_t * font = lv_font_load(be_tostring(vm, 1));
if (font != NULL) {
be_find_global_or_module_member(vm, "lv.lv_font");
be_pushcomptr(vm, font);
be_call(vm, 1);
be_pop(vm, 1);
be_return(vm);
} else {
be_return_nil(vm);
}
}
be_raise(vm, "type_error", NULL);
}
/*********************************************************************************************\
* LVGL top level virtual members
*
* Responds to virtual constants
\*********************************************************************************************/
extern const be_ntv_func_def_t lv_func[];
extern const size_t lv_func_size;
extern const be_const_member_t lv0_constants[];
extern const size_t lv0_constants_size;
extern const be_ctypes_class_by_name_t be_ctypes_lvgl_classes[];
extern const size_t be_ctypes_lvgl_classes_size;
int lv0_member(bvm *vm);
int lv0_member(bvm *vm) {
// first try the standard way
if (be_const_member(vm, lv0_constants, lv0_constants_size)) {
be_return(vm);
}
// try alternative members
int32_t argc = be_top(vm); // Get the number of arguments
if (argc == 1 && be_isstring(vm, 1)) {
const char * needle = be_tostring(vm, 1);
int32_t idx;
// search for a class with this name
char cl_prefixed[32];
snprintf(cl_prefixed, sizeof(cl_prefixed), "lv_%s", needle); // we try both actual name and prefixed with `lv_` so both `lv.obj` and `lv.lv_obj` work
idx = be_map_bin_search(cl_prefixed, &lv_classes[0].name, sizeof(lv_classes[0]), lv_classes_size);
if (idx < 0) {
idx = be_map_bin_search(needle, &lv_classes[0].name, sizeof(lv_classes[0]), lv_classes_size);
}
if (idx >= 0) {
// we did have a match
be_pushntvclass(vm, lv_classes[idx].cl);
be_return(vm);
}
// same search for ctypes
idx = be_map_bin_search(cl_prefixed, &be_ctypes_lvgl_classes[0].name, sizeof(be_ctypes_lvgl_classes[0]), be_ctypes_lvgl_classes_size);
if (idx < 0) {
idx = be_map_bin_search(needle, &be_ctypes_lvgl_classes[0].name, sizeof(be_ctypes_lvgl_classes[0]), be_ctypes_lvgl_classes_size);
}
if (idx >= 0) {
// we did have a match
be_pushntvclass(vm, be_ctypes_lvgl_classes[idx].cl);
be_return(vm);
}
// search for a method with this name
idx = be_map_bin_search(needle, &lv_func[0].name, sizeof(lv_func[0]), lv_func_size);
if (idx >= 0) {
const be_ntv_func_def_t * method = &lv_func[idx];
// push native closure
be_pushntvclosure(vm, &lv_x_call_c, 3); // 3 upvals
be_pushcomptr(vm, method->func);
be_setupval(vm, -2, 0);
be_pop(vm, 1);
be_pushstring(vm, method->return_type);
be_setupval(vm, -2, 1);
be_pop(vm, 1);
be_pushstring(vm, method->arg_type);
be_setupval(vm, -2, 2);
be_pop(vm, 1);
// all good
be_return(vm);
}
}
be_return_nil(vm);
}

View File

@ -0,0 +1,33 @@
#ifndef __LV_BERRY__
#define __LV_BERRY__
#ifdef __cplusplus
extern "C" {
#endif
#include "berry.h"
#include "lvgl.h"
/*********************************************************************************************\
* Support for lv_color
\*********************************************************************************************/
inline lv_color_t lv_color_from_uint32(uint32_t ucol) {
lv_color_t * col = (lv_color_t*) &ucol;
return *col;
}
inline uint32_t lv_color_to_uint32(lv_color_t col) {
uint16_t *p = (uint16_t*) &col;
return *p;
}
extern void be_load_lvgl_classes(bvm *vm);
// TODO temporary fix
extern void lv_img_set_tasmota_logo(lv_obj_t * img);
#ifdef __cplusplus
}
#endif
#endif // __LV_BERRY__

View File

@ -1,11 +1,11 @@
import re
import sys
lv_widgets_file = "lv_funcs.h"
lv_module_file = "lv_enum.h"
lv_widgets_file = "../mapping/lv_funcs.h"
lv_module_file = "../mapping/lv_enum.h"
out_prefix = "../../tasmota/lvgl_berry/"
lvgl_prefix = "../../lib/libesp32/Berry/default/"
out_prefix = "../generate/"
lvgl_prefix = "../generate/"
be_lv_defines = "be_lv_defines.h"
be_lv_c_mapping = "be_lv_c_mapping.h"
@ -320,13 +320,14 @@ extern "C" {
#endif
#include "be_ctypes.h"
#include "be_mapping.h"
""")
for subtype, flv in lv.items():
print(f"/* `lv_{subtype}` methods */")
if subtype in lv_widgets:
print(f"#ifdef BE_LV_WIDGET_{subtype.upper()}")
print(f"const lvbe_call_c_t lv_{subtype}_func[] = {{")
print(f"const be_ntv_func_def_t lv_{subtype}_func[] = {{")
func_out = {} # used to sort output
for f in flv:
@ -361,7 +362,7 @@ print()
# print the global map of classes
print(f"""
// map of clases
const lvbe_call_c_classes_t lv_classes[] = {{""")
const be_ntv_class_def_t lv_classes[] = {{""")
for subtype in sorted(lv):
# for subtype, flv in lv.items():
@ -391,7 +392,7 @@ for subtype, flv in lv.items():
if len(c_ret_type) > 1: c_ret_type = "lv." + c_ret_type
if c_func_name.endswith("_create"):
c_ret_type = "+" # constructor, init method does not return any value
c_ret_type = "+_p" # constructor, init method does not return any value
if subtype in lv_widgets:
print(f"#ifdef BE_LV_WIDGET_{subtype.upper()}")
print(f" int be_ntv_lv_{subtype}_init(bvm *vm) {{ return be_call_c_func(vm, (void*) &{orig_func_name}, \"{c_ret_type}\", { c_argc if c_argc else 'nullptr'}); }}")
@ -401,8 +402,8 @@ for subtype, flv in lv.items():
print("""
// create font either empty or from parameter on stack
int lvbe_font_create(bvm *vm) { return be_call_c_func(vm, NULL, "+lv_font", ""); }
int lvbe_theme_create(bvm *vm) { return be_call_c_func(vm, NULL, "+lv_theme", ""); }
int lvbe_font_create(bvm *vm) { return be_call_c_func(vm, NULL, "+_p", ""); }
int lvbe_theme_create(bvm *vm) { return be_call_c_func(vm, NULL, "+_p", ""); }
""")
print()
@ -424,8 +425,6 @@ print("""
*******************************************************************/
#include "be_constobj.h"
#ifdef USE_LVGL
#include "lvgl.h"
extern int lv0_init(bvm *vm);
@ -434,11 +433,11 @@ extern int lco_init(bvm *vm); // generic function
extern int lco_tostring(bvm *vm); // generic function
extern int lco_toint(bvm *vm); // generic function
extern int lvx_member(bvm *vm);
extern int lvx_tostring(bvm *vm); // generic function
extern int lv_x_member(bvm *vm);
extern int lv_x_tostring(bvm *vm); // generic function
extern int lvs_init(bvm *vm);
extern int lvs_tostring(bvm *vm);
extern int lv_x_tostring(bvm *vm);
BE_EXPORT_VARIABLE extern const bclass be_class_lv_obj;
@ -485,9 +484,9 @@ be_local_class(lv_style,
be_nested_map(4,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("init", 380752755, 4, -1), be_const_func(lvs_init) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lvs_tostring) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lv_x_tostring) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lvx_member) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lv_x_member) },
})),
(be_nested_const_str("lv_style", -143355747, 8))
);
@ -501,8 +500,8 @@ be_local_class(lv_obj,
NULL,
be_nested_map(5,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("tostring", -1995258651, 8, 3), be_const_func(lvx_tostring) },
{ be_nested_key("member", 719708611, 6, -1), be_const_func(lvx_member) },
{ be_nested_key("tostring", -1995258651, 8, 3), be_const_func(lv_x_tostring) },
{ be_nested_key("member", 719708611, 6, -1), be_const_func(lv_x_member) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
{ be_nested_key("init", 380752755, 4, 4), be_const_func(be_ntv_lv_obj_init) },
{ be_nested_key("_class", -1562820946, 6, -1), be_const_comptr(&lv_obj_class) },
@ -520,9 +519,9 @@ be_local_class(lv_group,
be_nested_map(4,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("init", 380752755, 4, -1), be_const_func(be_ntv_lv_group_init) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lvx_tostring) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lv_x_tostring) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lvx_member) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lv_x_member) },
})),
(be_nested_const_str("lv_group", -442928277, 8))
);
@ -537,9 +536,9 @@ be_local_class(lv_indev,
be_nested_map(4,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("init", 380752755, 4, -1), be_const_func(lv0_init) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lvx_tostring) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lv_x_tostring) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lvx_member) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lv_x_member) },
})),
(be_nested_const_str("lv_indev", 225602374, 8))
);
@ -554,9 +553,9 @@ be_local_class(lv_disp,
be_nested_map(4,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("init", 380752755, 4, -1), be_const_func(lv0_init) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lvx_tostring) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lv_x_tostring) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lvx_member) },
{ be_nested_key("member", 719708611, 6, 0), be_const_func(lv_x_member) },
})),
(be_nested_const_str("lv_disp", 609712084, 8))
);
@ -571,7 +570,7 @@ be_local_class(lv_font,
be_nested_map(3,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("init", 380752755, 4, -1), be_const_func(lvbe_font_create) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lvx_tostring) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lv_x_tostring) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
})),
(be_nested_const_str("lv_font", 1550958453, 7))
@ -587,7 +586,7 @@ be_local_class(lv_theme,
be_nested_map(3,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("init", 380752755, 4, -1), be_const_func(lvbe_theme_create) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lvx_tostring) },
{ be_nested_key("tostring", -1995258651, 8, -1), be_const_func(lv_x_tostring) },
{ be_nested_key("_p", 1594591802, 2, -1), be_const_var(0) },
})),
(be_nested_const_str("lv_theme", 1550958453, 7))
@ -641,9 +640,6 @@ be_local_class(lv_{subtype},
}}
""")
print("""
#endif // USE_LVGL
""")
sys.stdout.close()
@ -657,10 +653,8 @@ print("""/********************************************************************
*******************************************************************/
#include "be_constobj.h"
#ifdef USE_LVGL
#include "lvgl.h"
#include "be_lvgl.h"
#include "be_mapping.h"
#include "lv_theme_openhasp.h"
extern int lv0_member(bvm *vm); // resolve virtual members
@ -685,7 +679,7 @@ static int lv_get_ver_res(void) {
}
/* `lv` methods */
const lvbe_call_c_t lv_func[] = {
const be_ntv_func_def_t lv_func[] = {
""")
func_out = {} # used to sort output
@ -728,12 +722,7 @@ const size_t lv_func_size = sizeof(lv_func) / sizeof(lv_func[0]);
print("""
typedef struct be_constint_t {
const char * name;
int32_t value;
} be_constint_t;
const be_constint_t lv0_constants[] = {
const be_const_member_t lv0_constants[] = {
""")
lv_module2 = {}
@ -782,8 +771,6 @@ be_local_module(lv,
}))
);
BE_EXPORT_VARIABLE be_define_const_native_module(lv);
#endif // USE_LVGL
""")
print("/********************************************************************/")

View File

@ -48,7 +48,7 @@ def clean_source(raw):
# Parse function signatures
# ################################################################################
lv_src_prefix = "../../lib/libesp32_lvgl/LVGL8/src/"
lv_src_prefix = "../../lvgl/src/"
lv_fun_globs = [
"widgets/*.h", # all widgets
# "extra/widgets/*/*.h",
@ -69,14 +69,14 @@ lv_fun_globs = [
#"**/*.h",
]
headers_names = list_files(lv_src_prefix, lv_fun_globs)
headers_names += list_files("../../lib/libesp32_lvgl/LVGL_assets/src/", ["lv_theme_openhasp.h"])
headers_names += list_files("../../LVGL_assets/src/", ["lv_theme_openhasp.h"])
# headers_names += ["lv_pre_style.h"] # for LVGL v7, add pre-generated style functions from C preprocessor
# unit test
# headers_names = [ '../../lib/libesp32_lvgl/LVGL/src/lv_widgets/lv_btn.h' ]
# headers_names = [ '../../lib/libesp32_lvgl/LVGL/src/lv_api_map.h' ]
output_filename = "lv_funcs.h"
output_filename = "../mapping/lv_funcs.h"
sys.stdout = open(output_filename, 'w')
print("""
@ -169,11 +169,11 @@ sys.stdout.close()
# Parse 'enum'
# ################################################################################
lv_src_prefix = "../../lib/libesp32_lvgl/LVGL8/src/"
lv_src_prefix = "../../lvgl/src/"
lv_fun_globs = [ "**/*.h" ]
headers_names = list_files(lv_src_prefix, lv_fun_globs)
output_filename = "lv_enum.h"
output_filename = "../mapping/lv_enum.h"
sys.stdout = open(output_filename, 'w')
print("""// ======================================================================
// Functions

View File

@ -12,8 +12,8 @@
},
"license": "MIT",
"homepage": "https://lvgl.io",
"frameworks": "*",
"platforms": "*",
"frameworks": "arduino",
"platforms": "espressif32",
"build": {
"flags": [ "-I$PROJECT_DIR/tasmota/lvgl_berry" ]
}

Some files were not shown because too many files have changed in this diff Show More