mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 08:06:46 +01:00
M3 v0027 re-release, including M3 1.3 peghook support
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
|
||||
#define BUTTON1 28
|
||||
#define BUTTON2 29
|
||||
#define PEGHOOK_BUTTON 23
|
||||
|
||||
#define EPD_RST 4
|
||||
#define EPD_BS 2
|
||||
@@ -101,11 +102,16 @@ class epdInterface {
|
||||
|
||||
extern epdInterface* epd;
|
||||
|
||||
#define NRF_BOARDTYPE_REGULAR 0
|
||||
#define NRF_BOARDTYPE_PEGHOOK 1
|
||||
|
||||
struct tagSpecs {
|
||||
uint8_t buttonCount = 0;
|
||||
bool hasNFC = false;
|
||||
bool hasLED = false;
|
||||
bool ledInverted = false;
|
||||
bool hasThirdColor = false;
|
||||
uint8_t boardType = NRF_BOARDTYPE_REGULAR;
|
||||
uint16_t macSuffix = 0x0000;
|
||||
uint8_t OEPLtype = 0;
|
||||
uint8_t solumType = 0;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "wdt.h"
|
||||
#include "stdarg.h"
|
||||
|
||||
|
||||
bool epdGPIOActive = false;
|
||||
|
||||
void epdReset() {
|
||||
@@ -32,15 +31,18 @@ void epdConfigGPIO(bool setup) {
|
||||
pinMode(EPD_CLK, OUTPUT);
|
||||
pinMode(EPD_MOSI, OUTPUT);
|
||||
|
||||
pinMode(EPD_HLT, OUTPUT);
|
||||
pinMode(EPD_VPP, INPUT);
|
||||
switch (tag.boardType) {
|
||||
case NRF_BOARDTYPE_REGULAR:
|
||||
pinMode(EPD_HLT, OUTPUT);
|
||||
pinMode(EPD_VPP, INPUT);
|
||||
digitalWrite(EPD_HLT, HIGH);
|
||||
break;
|
||||
}
|
||||
|
||||
digitalWrite(EPD_BS, LOW); // low works!
|
||||
digitalWrite(EPD_CS, HIGH);
|
||||
digitalWrite(EPD_HLT, HIGH);
|
||||
|
||||
epdHardSPI(true);
|
||||
|
||||
} else {
|
||||
epdHardSPI(false);
|
||||
|
||||
@@ -52,9 +54,15 @@ void epdConfigGPIO(bool setup) {
|
||||
pinMode(EPD_BUSY, OUTPUT);
|
||||
pinMode(EPD_CLK, OUTPUT);
|
||||
pinMode(EPD_MOSI, OUTPUT);
|
||||
pinMode(EPD_HLT, OUTPUT);
|
||||
pinMode(EPD_VPP, OUTPUT);
|
||||
|
||||
switch (tag.boardType) {
|
||||
case NRF_BOARDTYPE_REGULAR:
|
||||
pinMode(EPD_HLT, OUTPUT);
|
||||
pinMode(EPD_VPP, OUTPUT);
|
||||
digitalWrite(EPD_HLT, LOW);
|
||||
digitalWrite(EPD_VPP, LOW);
|
||||
break;
|
||||
}
|
||||
digitalWrite(EPD_RST, LOW);
|
||||
digitalWrite(EPD_BS, LOW);
|
||||
digitalWrite(EPD_CS, LOW);
|
||||
@@ -62,8 +70,6 @@ void epdConfigGPIO(bool setup) {
|
||||
digitalWrite(EPD_BUSY, LOW);
|
||||
digitalWrite(EPD_CLK, LOW);
|
||||
digitalWrite(EPD_MOSI, LOW);
|
||||
digitalWrite(EPD_HLT, LOW);
|
||||
digitalWrite(EPD_VPP, LOW);
|
||||
}
|
||||
epdGPIOActive = setup;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ void identifyTagInfo() {
|
||||
72 92 1E 7E 15 0B 09 04 00 15 00 80 01 A8 00 38 00 01 01 9C 00 00 22 FF FF FF FF FF FF FF FF FF 2.9" FREEZER
|
||||
31 50 53 06 16 02 19 04 00 12 01 C8 00 C8 00 04 00 07 01 9C 00 00 40 FF FF FF FF FF FF FF FF FF
|
||||
|
||||
2F A5 03 06 15 0C 07 04 00 15 00 80 01 A8 00 38 00 07 81 1D 00 00 4E FF FF FF FF FF FF FF FF FF 2.9-unknown?
|
||||
4B F3 DE 04 15 05 07 04 00 0F 01 C8 00 90 00 38 00 07 01 19 00 00 4D FF FF FF FF FF FF FF FF FF 1.3-peghook
|
||||
|
||||
|
||||
|
||||
MAC | calib | |?????|Xres |Yres | ??? |capab| |type|
|
||||
@@ -153,7 +156,6 @@ void identifyTagInfo() {
|
||||
epd->epdMirrorV = true;
|
||||
tag.OEPLtype = SOLUM_M3_BWR_16;
|
||||
epd->effectiveXRes = epdXRes;
|
||||
epd->effectiveYRes = epdYRes - 1; // Yeah... I wonder why too....
|
||||
break;
|
||||
case STYPE_SIZE_022:
|
||||
tag.macSuffix = 0xB190;
|
||||
@@ -221,6 +223,17 @@ void identifyTagInfo() {
|
||||
epd->drawDirectionRight = true;
|
||||
tag.OEPLtype = SOLUM_M3_BWR_97;
|
||||
break;
|
||||
case STYPE_SIZE_013:
|
||||
//epdXRes -= 1;
|
||||
tag.ledInverted = true;
|
||||
tag.macSuffix = 0xBDB0;
|
||||
epd->drawDirectionRight = true;
|
||||
epd->effectiveXRes = epdYRes;
|
||||
epd->effectiveYRes = epdXRes;
|
||||
tag.OEPLtype = SOLUM_M3_PEGHOOK_BWR_13;
|
||||
tag.boardType = NRF_BOARDTYPE_PEGHOOK;
|
||||
epd->XOffset = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
if (epd->drawDirectionRight) {
|
||||
|
||||
@@ -130,7 +130,7 @@ void unissd::epdWriteDisplayData() {
|
||||
if (epd->epdMirrorV) {
|
||||
epdWrite(CMD_YSTART_POS, 2, this->YOffset & 0xFF, (this->YOffset) >> 8);
|
||||
} else {
|
||||
epdWrite(CMD_YSTART_POS, 2, (this->YOffset + this->effectiveYRes) & 0xFF, (this->YOffset + this->effectiveYRes) >> 8);
|
||||
epdWrite(CMD_YSTART_POS, 2, (this->YOffset + this->effectiveYRes -1) & 0xFF, (this->YOffset + this->effectiveYRes-1) >> 8);
|
||||
}
|
||||
break;
|
||||
case 0x19:
|
||||
@@ -143,7 +143,7 @@ void unissd::epdWriteDisplayData() {
|
||||
delay(10);
|
||||
markData();
|
||||
epdSelect();
|
||||
for (uint16_t curY = 0; curY < epd->effectiveYRes; curY += 2) {
|
||||
for (uint16_t curY = 0+epd->YOffset; curY < (epd->effectiveYRes+epd->YOffset); curY += 2) {
|
||||
// Get 'even' screen line
|
||||
buf[0] = (uint8_t *)calloc(epd->effectiveXRes / 8, 1);
|
||||
|
||||
|
||||
@@ -446,12 +446,12 @@ void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
setupPortsInitial();
|
||||
powerUp(INIT_BASE | INIT_UART);
|
||||
printf("BOOTED> %04X-%s\n", fwVersion, fwVersionSuffix);
|
||||
|
||||
wakeUpReason = getFirstWakeUpReason();
|
||||
identifyTagInfo();
|
||||
setupPortsInitial();
|
||||
boardGetOwnMac(mSelfMac);
|
||||
|
||||
// do something if the mac isn't valid
|
||||
|
||||
@@ -51,14 +51,31 @@ void nfcwake() {
|
||||
}
|
||||
|
||||
void setupPortsInitial() {
|
||||
digitalWrite(LED_RED, HIGH);
|
||||
digitalWrite(LED_GREEN, HIGH);
|
||||
digitalWrite(LED_BLUE, HIGH);
|
||||
if (tag.ledInverted) {
|
||||
digitalWrite(LED_RED, LOW);
|
||||
digitalWrite(LED_GREEN, LOW);
|
||||
digitalWrite(LED_BLUE, LOW);
|
||||
} else {
|
||||
digitalWrite(LED_RED, HIGH);
|
||||
digitalWrite(LED_GREEN, HIGH);
|
||||
digitalWrite(LED_BLUE, HIGH);
|
||||
}
|
||||
pinMode(LED_RED, OUTPUT);
|
||||
pinMode(LED_GREEN, OUTPUT);
|
||||
pinMode(LED_BLUE, OUTPUT);
|
||||
pinMode(BUTTON1, INPUT_PULLUP);
|
||||
pinMode(BUTTON2, INPUT_PULLUP);
|
||||
switch (tag.boardType) {
|
||||
case NRF_BOARDTYPE_REGULAR:
|
||||
pinMode(BUTTON1, INPUT_PULLUP);
|
||||
pinMode(BUTTON2, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(BUTTON1), button1wake, FALLING);
|
||||
attachInterrupt(digitalPinToInterrupt(BUTTON2), button2wake, FALLING);
|
||||
break;
|
||||
case NRF_BOARDTYPE_PEGHOOK:
|
||||
pinMode(PEGHOOK_BUTTON, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(PEGHOOK_BUTTON), button1wake, FALLING);
|
||||
break;
|
||||
}
|
||||
|
||||
pinMode(NFC_POWER, INPUT_PULLDOWN);
|
||||
pinMode(NFC_IRQ, INPUT_PULLDOWN);
|
||||
|
||||
@@ -76,8 +93,6 @@ void setupPortsInitial() {
|
||||
// pinMode(EPD_HLT, OUTPUT);
|
||||
// digitalWrite(EPD_HLT, HIGH);
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(BUTTON1), button1wake, FALLING);
|
||||
attachInterrupt(digitalPinToInterrupt(BUTTON2), button2wake, FALLING);
|
||||
attachInterrupt(digitalPinToInterrupt(NFC_IRQ), nfcwake, RISING);
|
||||
}
|
||||
|
||||
@@ -212,7 +227,7 @@ void powerDown(const uint8_t parts) {
|
||||
}
|
||||
|
||||
void doSleep(const uint32_t t) {
|
||||
//printf("Sleeping for: %lu ms\r\n", t);
|
||||
// printf("Sleeping for: %lu ms\r\n", t);
|
||||
sleepForMs(t);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,15 +26,14 @@ bool lowBatteryShown = false;
|
||||
bool noAPShown = false;
|
||||
|
||||
void addOverlay() {
|
||||
|
||||
if (currentChannel == 0) {
|
||||
drawMask(epd->Xres - 28, 4, 24, 24, COLOR_BLACK);
|
||||
if(tag.hasThirdColor){
|
||||
if (tag.hasThirdColor) {
|
||||
drawMask(epd->Xres - 28, 4, 24, 24, COLOR_RED);
|
||||
drawRoundedRectangle(epd->Xres - 28, 4, 24, 24, COLOR_RED);
|
||||
addBufferedImage(epd->Xres - 24, 8, COLOR_BLACK, rotation::ROTATE_0, ant, DRAW_NORMAL);
|
||||
addBufferedImage(epd->Xres - 16, 15, COLOR_RED, rotation::ROTATE_0, cross, DRAW_NORMAL);
|
||||
}else{
|
||||
} else {
|
||||
drawRoundedRectangle(epd->Xres - 28, 4, 24, 24, COLOR_BLACK);
|
||||
addBufferedImage(epd->Xres - 24, 8, COLOR_BLACK, rotation::ROTATE_0, ant, DRAW_NORMAL);
|
||||
addBufferedImage(epd->Xres - 16, 15, COLOR_BLACK, rotation::ROTATE_0, cross, DRAW_NORMAL);
|
||||
@@ -46,10 +45,10 @@ void addOverlay() {
|
||||
|
||||
if (lowBattery) {
|
||||
drawMask(epd->Xres - 27, epd->Yres - 26, 22, 22, COLOR_BLACK);
|
||||
if(tag.hasThirdColor){
|
||||
if (tag.hasThirdColor) {
|
||||
drawMask(epd->Xres - 27, epd->Yres - 26, 22, 22, COLOR_RED);
|
||||
drawRoundedRectangle(epd->Xres - 28, epd->Yres - 26, 24, 24, COLOR_RED);
|
||||
}else{
|
||||
} else {
|
||||
drawMask(epd->Xres - 27, epd->Yres - 26, 22, 22, COLOR_BLACK);
|
||||
drawRoundedRectangle(epd->Xres - 28, epd->Yres - 26, 24, 24, COLOR_BLACK);
|
||||
}
|
||||
@@ -61,11 +60,11 @@ void addOverlay() {
|
||||
#ifdef DEBUG_BUILD
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
drawMask(15, epd->Yres - 53, 130, 33, COLOR_BLACK);
|
||||
if(tag.hasThirdColor){
|
||||
if (tag.hasThirdColor) {
|
||||
drawMask(15, epd->Yres - 53, 130, 33, COLOR_RED);
|
||||
drawRoundedRectangle(15, epd->Yres - 53, 129, 33, COLOR_RED);
|
||||
fr.epdPrintf(17, epd->Yres - 50, COLOR_RED, rotation::ROTATE_0, "DEBUG");
|
||||
}else{
|
||||
} else {
|
||||
drawMask(15, epd->Yres - 53, 130, 33, COLOR_BLACK);
|
||||
drawRoundedRectangle(15, epd->Yres - 53, 129, 33, COLOR_BLACK);
|
||||
fr.epdPrintf(17, epd->Yres - 50, COLOR_BLACK, rotation::ROTATE_0, "DEBUG");
|
||||
@@ -83,9 +82,14 @@ void showSplashScreen() {
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
switch (tag.solumType) {
|
||||
case STYPE_SIZE_016:
|
||||
case STYPE_SIZE_013:
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(2, 2, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
if(tag.solumType==STYPE_SIZE_013){
|
||||
fr.epdPrintf(2, 38, COLOR_RED, rotation::ROTATE_0, "Newton M3 1.3 Peghook\"");
|
||||
} else {
|
||||
fr.epdPrintf(10, 38, COLOR_RED, rotation::ROTATE_0, "Newton M3 1.6\"");
|
||||
}
|
||||
fr.epdPrintf(5, epd->Yres - 40, 0, rotation::ROTATE_0, "FW: %04X-%s", fwVersion, fwVersionSuffix);
|
||||
fr.epdPrintf(2, epd->Yres - 20, 0, rotation::ROTATE_0, "%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
@@ -205,12 +209,12 @@ void showSplashScreen() {
|
||||
}
|
||||
#ifdef DEBUG_BUILD
|
||||
drawMask(15, epd->Yres - 53, 129, 33, COLOR_BLACK);
|
||||
if(tag.hasThirdColor){
|
||||
if (tag.hasThirdColor) {
|
||||
drawMask(15, epd->Yres - 53, 129, 33, COLOR_RED);
|
||||
drawRoundedRectangle(15, epd->Yres - 53, 129, 33, COLOR_RED);
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(17, epd->Yres - 50, COLOR_RED, rotation::ROTATE_0, "DEBUG");
|
||||
}else{
|
||||
} else {
|
||||
drawMask(15, epd->Yres - 53, 129, 33, COLOR_BLACK);
|
||||
drawRoundedRectangle(15, epd->Yres - 53, 129, 33, COLOR_BLACK);
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
@@ -241,6 +245,7 @@ void showAPFound() {
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
switch (tag.solumType) {
|
||||
case STYPE_SIZE_016:
|
||||
case STYPE_SIZE_013:
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(7, 6, COLOR_BLACK, rotation::ROTATE_0, "AP Found");
|
||||
fr.epdPrintf(0, 24, COLOR_RED, rotation::ROTATE_0, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
@@ -249,7 +254,6 @@ void showAPFound() {
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(5, epd->Yres - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(0, epd->Yres - 25, 0, rotation::ROTATE_0, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
|
||||
break;
|
||||
case STYPE_SIZE_022:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
@@ -396,6 +400,7 @@ void showNoAP() {
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
switch (tag.solumType) {
|
||||
case STYPE_SIZE_016:
|
||||
case STYPE_SIZE_013:
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "NO AP Found");
|
||||
fr.epdPrintf(2, 25, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
|
||||
BIN
Hardware/Uncommon Tag Jigs/EL013H2WRD-Peghook.skp
Normal file
BIN
Hardware/Uncommon Tag Jigs/EL013H2WRD-Peghook.skp
Normal file
Binary file not shown.
BIN
Hardware/Uncommon Tag Jigs/EL013H2WRD-Peghook.stl
Normal file
BIN
Hardware/Uncommon Tag Jigs/EL013H2WRD-Peghook.stl
Normal file
Binary file not shown.
BIN
Hardware/Yellow AP Case/YellowAP Mini Case-cover.stl
Normal file
BIN
Hardware/Yellow AP Case/YellowAP Mini Case-cover.stl
Normal file
Binary file not shown.
BIN
Hardware/Yellow AP Case/YellowAP Mini Case.skp
Normal file
BIN
Hardware/Yellow AP Case/YellowAP Mini Case.skp
Normal file
Binary file not shown.
BIN
Hardware/Yellow AP Case/YellowAP Mini Case.stl
Normal file
BIN
Hardware/Yellow AP Case/YellowAP Mini Case.stl
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -33,62 +33,67 @@
|
||||
"2E": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "03311a065fe4e1d20f373df7bc5f8dbe"
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
},
|
||||
"2F": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "03311a065fe4e1d20f373df7bc5f8dbe"
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
},
|
||||
"30": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "03311a065fe4e1d20f373df7bc5f8dbe"
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
},
|
||||
"31": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "03311a065fe4e1d20f373df7bc5f8dbe"
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
},
|
||||
"32": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "03311a065fe4e1d20f373df7bc5f8dbe"
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
},
|
||||
"33": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "03311a065fe4e1d20f373df7bc5f8dbe"
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
},
|
||||
"34": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "03311a065fe4e1d20f373df7bc5f8dbe"
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
},
|
||||
"35": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "03311a065fe4e1d20f373df7bc5f8dbe"
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
},
|
||||
"36": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "03311a065fe4e1d20f373df7bc5f8dbe"
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
},
|
||||
"40": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "03311a065fe4e1d20f373df7bc5f8dbe"
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
},
|
||||
"41": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "03311a065fe4e1d20f373df7bc5f8dbe"
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
},
|
||||
"42": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "03311a065fe4e1d20f373df7bc5f8dbe"
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
},
|
||||
"43": {
|
||||
"type": "SOL_M3_Uni_ota",
|
||||
"version": "0027",
|
||||
"md5": "55541b0f440e041d559c4d72c9dee524"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
@@ -55,6 +55,8 @@
|
||||
#define SOLUM_M3_BW_29 0x40
|
||||
#define SOLUM_M3_BWR_58 0x41
|
||||
#define SOLUM_M3_BW_58 0x42
|
||||
#define SOLUM_M3_PEGHOOK_BWR_13 0x43
|
||||
|
||||
|
||||
// Hanshow Nebular types
|
||||
#define HS_NEBULAR_BWY_35 0x60
|
||||
@@ -90,6 +92,9 @@
|
||||
#define STYPE_SIZE_060 0x48
|
||||
#define STYPE_SIZE_075 0x4C
|
||||
#define STYPE_SIZE_097 0x64
|
||||
#define STYPE_SIZE_013 0x4D
|
||||
|
||||
|
||||
|
||||
|
||||
// Capability flags
|
||||
|
||||
Reference in New Issue
Block a user