update
This commit is contained in:
commit
501164811b
BIN
Dokumentation.odt
Normal file
BIN
Dokumentation.odt
Normal file
Binary file not shown.
BIN
Dokumentation.pdf
Normal file
BIN
Dokumentation.pdf
Normal file
Binary file not shown.
24
ESP32DatabaseInsert_SetUp/Credentials.h
Normal file
24
ESP32DatabaseInsert_SetUp/Credentials.h
Normal file
@ -0,0 +1,24 @@
|
||||
/****************************************************************************************************************************
|
||||
Credentials.h
|
||||
Library for communicating with a MySQL or MariaDB Server
|
||||
|
||||
Based on and modified from Dr. Charles A. Bell's MySQL_Connector_Arduino Library https://github.com/ChuckBell/MySQL_Connector_Arduino
|
||||
to support nRF52, SAMD21/SAMD51, SAM DUE, STM32F/L/H/G/WB/MP1, ESP8266, ESP32, etc. boards using W5x00, ENC28J60, LAM8742A Ethernet,
|
||||
WiFiNINA, ESP-AT, built-in ESP8266/ESP32 WiFi.
|
||||
|
||||
The library provides simple and easy Client interface to MySQL or MariaDB Server.
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/MySQL_MariaDB_Generic
|
||||
Licensed under MIT license
|
||||
**********************************************************************************************************************************/
|
||||
|
||||
#ifndef Credentials_h
|
||||
#define Credentials_h
|
||||
|
||||
char ssid[] = "cpsNUCwifi"; // your network SSID (name)
|
||||
char pass[] = "ips999CPS"; // your network password
|
||||
|
||||
char user[] = "db_user"; // MySQL user login username - db_user - DoItLabUser
|
||||
char password[] = "db_password"; // MySQL user login password - db_password - DoItLabDBPasswd
|
||||
|
||||
#endif //Credentials_h
|
192
ESP32DatabaseInsert_SetUp/ESP32DatabaseInsert_SetUp.ino
Normal file
192
ESP32DatabaseInsert_SetUp/ESP32DatabaseInsert_SetUp.ino
Normal file
@ -0,0 +1,192 @@
|
||||
/*********************************************************************************************************************************
|
||||
Basic_Insert_WiFi.ino
|
||||
|
||||
Library for communicating with a MySQL or MariaDB Server
|
||||
|
||||
Based on and modified from Dr. Charles A. Bell's MySQL_Connector_Arduino Library https://github.com/ChuckBell/MySQL_Connector_Arduino
|
||||
to support nRF52, SAMD21/SAMD51, SAM DUE, STM32F/L/H/G/WB/MP1, ESP8266, ESP32, etc. boards using W5x00, ENC28J60, LAM8742A Ethernet,
|
||||
WiFiNINA, ESP-AT, built-in ESP8266/ESP32 WiFi.
|
||||
|
||||
The library provides simple and easy Client interface to MySQL or MariaDB Server.
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/MySQL_MariaDB_Generic
|
||||
Licensed under MIT license
|
||||
**********************************************************************************************************************************/
|
||||
/*
|
||||
MySQL Connector/Arduino Example : basic insert
|
||||
|
||||
This example demonstrates how to issue an INSERT query to store data in a
|
||||
table. For this, we will create a special database and table for testing.
|
||||
The following are the SQL commands you will need to run in order to setup
|
||||
your database for running this sketch.
|
||||
|
||||
CREATE DATABASE test_arduino;
|
||||
CREATE TABLE test_arduino.hello_arduino (
|
||||
num integer primary key auto_increment,
|
||||
message char(40),
|
||||
recorded timestamp
|
||||
);
|
||||
|
||||
Here we see one database and a table with three fields; a primary key that
|
||||
is an auto_increment, a string, and a timestamp. This will demonstrate how
|
||||
to save a date and time of when the row was inserted, which can help you
|
||||
determine when data was recorded or updated.
|
||||
|
||||
For more information and documentation, visit the wiki:
|
||||
https://github.com/ChuckBell/MySQL_Connector_Arduino/wiki.
|
||||
|
||||
INSTRUCTIONS FOR USE
|
||||
|
||||
1) Create the database and table as shown above.
|
||||
2) Change the address of the server to the IP address of the MySQL server
|
||||
3) Change the user and password to a valid MySQL user and password
|
||||
4) Connect a USB cable to your Arduino
|
||||
5) Select the correct board and port
|
||||
6) Compile and upload the sketch to your Arduino
|
||||
7) Once uploaded, open Serial Monitor (use 115200 speed) and observe
|
||||
8) After the sketch has run for some time, open a mysql client and issue
|
||||
the command: "SELECT * FROM test_arduino.hello_arduino" to see the data
|
||||
recorded. Note the field values and how the database handles both the
|
||||
auto_increment and timestamp fields for us. You can clear the data with
|
||||
"DELETE FROM test_arduino.hello_arduino".
|
||||
|
||||
Note: The MAC address can be anything so long as it is unique on your network.
|
||||
|
||||
Created by: Dr. Charles A. Bell
|
||||
*/
|
||||
|
||||
#include "defines.h"
|
||||
#include "Credentials.h"
|
||||
|
||||
#include <MySQL_Generic.h>
|
||||
|
||||
#define USING_HOST_NAME false
|
||||
|
||||
#if USING_HOST_NAME
|
||||
// Optional using hostname, and Ethernet built-in DNS lookup
|
||||
char server[] = "your_account.ddns.net"; // change to your server's hostname/URL
|
||||
#else
|
||||
IPAddress server(10, 42, 0, 1);
|
||||
#endif
|
||||
|
||||
uint16_t server_port = 3306; //5698;
|
||||
|
||||
char default_database[] = "myTestDb"; //DoItLabDB
|
||||
char default_table[] = "myTestTable"; //QRCodeTable
|
||||
|
||||
String default_value = "ESP32_TestString";
|
||||
|
||||
// Sample query
|
||||
String INSERT_SQL = String("INSERT INTO ") + default_database + "." + default_table
|
||||
+ " (qrCodeText) VALUES ('" + default_value + "')";
|
||||
|
||||
|
||||
|
||||
|
||||
MySQL_Connection conn((Client *)&client);
|
||||
|
||||
MySQL_Query *query_mem;
|
||||
|
||||
//###################################################################################
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial && millis() < 5000); // wait for serial port to connect
|
||||
|
||||
MYSQL_DISPLAY1("\nStarting Basic_Insert_WiFi on", BOARD_NAME);
|
||||
MYSQL_DISPLAY(MYSQL_MARIADB_GENERIC_VERSION);
|
||||
|
||||
// Remember to initialize your WiFi module
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#if ( USING_WIFI_ESP8266_AT )
|
||||
MYSQL_DISPLAY("Using ESP8266_AT/ESP8266_AT_WebServer Library");
|
||||
#elif ( USING_WIFIESPAT_LIB )
|
||||
MYSQL_DISPLAY("Using WiFiEspAT Library");
|
||||
#endif
|
||||
|
||||
// initialize serial for ESP module
|
||||
EspSerial.begin(115200);
|
||||
// initialize ESP module
|
||||
WiFi.init(&EspSerial);
|
||||
|
||||
MYSQL_DISPLAY(F("WiFi shield init done"));
|
||||
|
||||
// check for the presence of the shield
|
||||
if (WiFi.status() == WL_NO_SHIELD)
|
||||
{
|
||||
MYSQL_DISPLAY(F("WiFi shield not present"));
|
||||
// don't continue
|
||||
while (true);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Begin WiFi section
|
||||
MYSQL_DISPLAY1("Connecting to", ssid);
|
||||
|
||||
WiFi.begin(ssid, pass);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
delay(500);
|
||||
MYSQL_DISPLAY0(".");
|
||||
}
|
||||
|
||||
// print out info about the connection:
|
||||
MYSQL_DISPLAY1("Connected to network. My IP address is:", WiFi.localIP());
|
||||
|
||||
MYSQL_DISPLAY3("Connecting to SQL Server @", server, ", Port =", server_port);
|
||||
MYSQL_DISPLAY5("User =", user, ", PW =", password, ", DB =", default_database);
|
||||
}
|
||||
|
||||
//###################################################################################
|
||||
void runInsert()
|
||||
{
|
||||
// Initiate the query class instance
|
||||
MySQL_Query query_mem = MySQL_Query(&conn);
|
||||
|
||||
if (conn.connected())
|
||||
{
|
||||
MYSQL_DISPLAY(INSERT_SQL);
|
||||
|
||||
// Execute the query
|
||||
// KH, check if valid before fetching
|
||||
if ( !query_mem.execute(INSERT_SQL.c_str()) )
|
||||
{
|
||||
MYSQL_DISPLAY("Insert error");
|
||||
}
|
||||
else
|
||||
{
|
||||
MYSQL_DISPLAY("Data Inserted.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MYSQL_DISPLAY("Disconnected from Server. Can't insert.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//###################################################################################
|
||||
void loop()
|
||||
{
|
||||
MYSQL_DISPLAY("Connecting...");
|
||||
|
||||
|
||||
|
||||
//if (conn.connect(server, server_port, user, password))
|
||||
if (conn.connectNonBlocking(server, server_port, user, password) != RESULT_FAIL)
|
||||
{
|
||||
delay(500);
|
||||
runInsert();
|
||||
conn.close(); // close the connection
|
||||
}
|
||||
else
|
||||
{
|
||||
MYSQL_DISPLAY("\nConnect failed. Trying again on next iteration.");
|
||||
}
|
||||
|
||||
MYSQL_DISPLAY("\nSleeping...");
|
||||
MYSQL_DISPLAY("================================================");
|
||||
|
||||
delay(60000);
|
||||
}
|
381
ESP32DatabaseInsert_SetUp/defines.h
Normal file
381
ESP32DatabaseInsert_SetUp/defines.h
Normal file
@ -0,0 +1,381 @@
|
||||
/****************************************************************************************************************************
|
||||
defines.h
|
||||
Library for communicating with a MySQL or MariaDB Server
|
||||
|
||||
Based on and modified from Dr. Charles A. Bell's MySQL_Connector_Arduino Library https://github.com/ChuckBell/MySQL_Connector_Arduino
|
||||
to support nRF52, SAMD21/SAMD51, SAM DUE, STM32F/L/H/G/WB/MP1, ESP8266, ESP32, etc. boards using W5x00, ENC28J60, LAM8742A Ethernet,
|
||||
WiFiNINA, ESP-AT, built-in ESP8266/ESP32 WiFi.
|
||||
|
||||
The library provides simple and easy Client interface to MySQL or MariaDB Server.
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/MySQL_MariaDB_Generic
|
||||
Licensed under MIT license
|
||||
**********************************************************************************************************************************/
|
||||
|
||||
#ifndef defines_h
|
||||
#define defines_h
|
||||
|
||||
#define DEBUG_ESP8266_AT_WEBSERVER_PORT Serial
|
||||
|
||||
// Debug Level from 0 to 4
|
||||
#define _ESP_AT_LOGLEVEL_ 1
|
||||
|
||||
#define MYSQL_DEBUG_PORT Serial
|
||||
|
||||
// Debug Level from 0 to 4
|
||||
#define _MYSQL_LOGLEVEL_ 1
|
||||
|
||||
#if ! (ESP8266 || ESP32 )
|
||||
// Select only one of these libraries, only for boards other than ESP8266/ESP32
|
||||
#define USING_WIFI_ESP8266_AT false
|
||||
#define USING_WIFININA_GENERIC false
|
||||
#define USING_WIFININA false
|
||||
#define USING_WIFIESPAT_LIB true
|
||||
#define USING_WIFI_CUSTOM false
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_SAMD_MKR1000)
|
||||
#if defined(USE_WIFI_NINA)
|
||||
#undef USE_WIFI_NINA
|
||||
#endif
|
||||
#define USE_WIFI_NINA false
|
||||
#define USE_WIFI101 true
|
||||
#endif
|
||||
|
||||
#if ( defined(NRF52840_FEATHER) || defined(NRF52832_FEATHER) || defined(NRF52_SERIES) || defined(ARDUINO_NRF52_ADAFRUIT) || \
|
||||
defined(NRF52840_FEATHER_SENSE) || defined(NRF52840_ITSYBITSY) || defined(NRF52840_CIRCUITPLAY) || defined(NRF52840_CLUE) || \
|
||||
defined(NRF52840_METRO) || defined(NRF52840_PCA10056) || defined(PARTICLE_XENON) || defined(NINA_B302_ublox) || defined(NINA_B112_ublox) )
|
||||
#if defined(WIFI_USE_NRF528XX)
|
||||
#undef WIFI_USE_NRF528XX
|
||||
#endif
|
||||
#define WIFI_USE_NRF528XX true
|
||||
#endif
|
||||
|
||||
#if ( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
|
||||
|| defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
|
||||
|| defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(__SAMD21G18A__) \
|
||||
|| defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD21E18A__) || defined(__SAMD51__) || defined(__SAMD51J20A__) || defined(__SAMD51J19A__) \
|
||||
|| defined(__SAMD51G19A__) || defined(__SAMD51P19A__) || defined(__SAMD21G18A__) )
|
||||
#if defined(WIFI_USE_SAMD)
|
||||
#undef WIFI_USE_SAMD
|
||||
#endif
|
||||
#define WIFI_USE_SAMD true
|
||||
#endif
|
||||
|
||||
#if ( defined(ARDUINO_SAM_DUE) || defined(__SAM3X8E__) )
|
||||
#if defined(WIFI_USE_SAM_DUE)
|
||||
#undef WIFI_USE_SAM_DUE
|
||||
#endif
|
||||
#define WIFI_USE_SAM_DUE true
|
||||
#warning Use SAM_DUE architecture
|
||||
#endif
|
||||
|
||||
#if ( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) ||defined(STM32F4) || defined(STM32F7) || \
|
||||
defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7) ||defined(STM32G0) || defined(STM32G4) || \
|
||||
defined(STM32WB) || defined(STM32MP1) )
|
||||
#if defined(WIFI_USE_STM32)
|
||||
#undef WIFI_USE_STM32
|
||||
#endif
|
||||
#define WIFI_USE_STM32 true
|
||||
#endif
|
||||
|
||||
#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_RASPBERRY_PI_PICO) || \
|
||||
defined(ARDUINO_GENERIC_RP2040) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) )
|
||||
#if defined(WIFI_USE_RP2040)
|
||||
#undef WIFI_USE_RP2040
|
||||
#endif
|
||||
#define WIFI_USE_RP2040 true
|
||||
#endif
|
||||
|
||||
#ifdef CORE_TEENSY
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
// For Teensy 4.1/4.0
|
||||
#define EspSerial Serial2 //Serial2, Pin RX2 : 7, TX2 : 8
|
||||
#endif
|
||||
|
||||
#if defined(__IMXRT1062__)
|
||||
// For Teensy 4.1/4.0
|
||||
#define BOARD_TYPE "TEENSY 4.1/4.0"
|
||||
#elif defined(__MK66FX1M0__)
|
||||
#define BOARD_TYPE "Teensy 3.6"
|
||||
#elif defined(__MK64FX512__)
|
||||
#define BOARD_TYPE "Teensy 3.5"
|
||||
#elif defined(__MKL26Z64__)
|
||||
#define BOARD_TYPE "Teensy LC"
|
||||
#elif defined(__MK20DX256__)
|
||||
#define BOARD_TYPE "Teensy 3.2" // and Teensy 3.1 (obsolete)
|
||||
#elif defined(__MK20DX128__)
|
||||
#define BOARD_TYPE "Teensy 3.0"
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
#error Teensy 2.0++ not supported yet
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#error Teensy 2.0 not supported yet
|
||||
#else
|
||||
// For Other Boards
|
||||
#define BOARD_TYPE "Unknown Teensy Board"
|
||||
#endif
|
||||
|
||||
#elif defined(WIFI_USE_NRF528XX)
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#if defined(NRF52840_FEATHER)
|
||||
#define BOARD_TYPE "NRF52840_FEATHER_EXPRESS"
|
||||
#elif defined(NRF52832_FEATHER)
|
||||
#define BOARD_TYPE "NRF52832_FEATHER"
|
||||
#elif defined(NRF52840_FEATHER_SENSE)
|
||||
#define BOARD_TYPE "NRF52840_FEATHER_SENSE"
|
||||
#elif defined(NRF52840_ITSYBITSY)
|
||||
#define BOARD_TYPE "NRF52840_ITSYBITSY_EXPRESS"
|
||||
#elif defined(NRF52840_CIRCUITPLAY)
|
||||
#define BOARD_TYPE "NRF52840_CIRCUIT_PLAYGROUND"
|
||||
#elif defined(NRF52840_CLUE)
|
||||
#define BOARD_TYPE "NRF52840_CLUE"
|
||||
#elif defined(NRF52840_METRO)
|
||||
#define BOARD_TYPE "NRF52840_METRO_EXPRESS"
|
||||
#elif defined(NRF52840_PCA10056)
|
||||
#define BOARD_TYPE "NORDIC_NRF52840DK"
|
||||
#elif defined(NINA_B302_ublox)
|
||||
#define BOARD_TYPE "NINA_B302_ublox"
|
||||
#elif defined(NINA_B112_ublox)
|
||||
#define BOARD_TYPE "NINA_B112_ublox"
|
||||
#elif defined(PARTICLE_XENON)
|
||||
#define BOARD_TYPE "PARTICLE_XENON"
|
||||
#elif defined(MDBT50Q_RX)
|
||||
#define BOARD_TYPE "RAYTAC_MDBT50Q_RX"
|
||||
#elif defined(ARDUINO_NRF52_ADAFRUIT)
|
||||
#define BOARD_TYPE "ARDUINO_NRF52_ADAFRUIT"
|
||||
#else
|
||||
#define BOARD_TYPE "nRF52 Unknown"
|
||||
#endif
|
||||
|
||||
#elif defined(WIFI_USE_SAMD)
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
// For SAMD
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_SAMD_ZERO)
|
||||
#define BOARD_TYPE "SAMD Zero"
|
||||
#elif defined(ARDUINO_SAMD_MKR1000)
|
||||
#define BOARD_TYPE "SAMD MKR1000"
|
||||
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
|
||||
#define BOARD_TYPE "SAMD MKRWIFI1010"
|
||||
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
|
||||
#define BOARD_TYPE "SAMD NANO_33_IOT"
|
||||
#elif defined(ARDUINO_SAMD_MKRFox1200)
|
||||
#define BOARD_TYPE "SAMD MKRFox1200"
|
||||
#elif ( defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) )
|
||||
#define BOARD_TYPE "SAMD MKRWAN13X0"
|
||||
#elif defined(ARDUINO_SAMD_MKRGSM1400)
|
||||
#define BOARD_TYPE "SAMD MKRGSM1400"
|
||||
#elif defined(ARDUINO_SAMD_MKRNB1500)
|
||||
#define BOARD_TYPE "SAMD MKRNB1500"
|
||||
#elif defined(ARDUINO_SAMD_MKRVIDOR4000)
|
||||
#define BOARD_TYPE "SAMD MKRVIDOR4000"
|
||||
#elif defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS"
|
||||
#elif defined(ADAFRUIT_FEATHER_M0_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_FEATHER_M0_EXPRESS"
|
||||
#elif defined(ADAFRUIT_METRO_M0_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_METRO_M0_EXPRESS"
|
||||
#elif defined(ADAFRUIT_CIRCUITPLAYGROUND_M0)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_CIRCUITPLAYGROUND_M0"
|
||||
#elif defined(ADAFRUIT_GEMMA_M0)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_GEMMA_M0"
|
||||
#elif defined(ADAFRUIT_TRINKET_M0)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_TRINKET_M0"
|
||||
#elif defined(ADAFRUIT_ITSYBITSY_M0)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_ITSYBITSY_M0"
|
||||
#elif defined(ARDUINO_SAMD_HALLOWING_M0)
|
||||
#define BOARD_TYPE "SAMD21 ARDUINO_SAMD_HALLOWING_M0"
|
||||
#elif defined(ADAFRUIT_METRO_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_METRO_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_GRAND_CENTRAL_M4)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_GRAND_CENTRAL_M4"
|
||||
#elif defined(ADAFRUIT_FEATHER_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_FEATHER_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_ITSYBITSY_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_ITSYBITSY_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_TRELLIS_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_TRELLIS_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_PYPORTAL)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYPORTAL"
|
||||
#elif defined(ADAFRUIT_PYPORTAL_M4_TITANO)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYPORTAL_M4_TITANO"
|
||||
#elif defined(ADAFRUIT_PYBADGE_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYBADGE_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_METRO_M4_AIRLIFT_LITE"
|
||||
#elif defined(ADAFRUIT_PYGAMER_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYGAMER_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_PYGAMER_ADVANCE_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYGAMER_ADVANCE_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_PYBADGE_AIRLIFT_M4)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYBADGE_AIRLIFT_M4"
|
||||
#elif defined(ADAFRUIT_MONSTER_M4SK_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_MONSTER_M4SK_EXPRESS"
|
||||
#elif defined(ADAFRUIT_HALLOWING_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_HALLOWING_M4_EXPRESS"
|
||||
#elif defined(SEEED_WIO_TERMINAL)
|
||||
#define BOARD_TYPE "SAMD SEEED_WIO_TERMINAL"
|
||||
#elif defined(SEEED_FEMTO_M0)
|
||||
#define BOARD_TYPE "SAMD SEEED_FEMTO_M0"
|
||||
#elif defined(SEEED_XIAO_M0)
|
||||
#define BOARD_TYPE "SAMD SEEED_XIAO_M0"
|
||||
#elif defined(Wio_Lite_MG126)
|
||||
#define BOARD_TYPE "SAMD SEEED Wio_Lite_MG126"
|
||||
#elif defined(WIO_GPS_BOARD)
|
||||
#define BOARD_TYPE "SAMD SEEED WIO_GPS_BOARD"
|
||||
#elif defined(SEEEDUINO_ZERO)
|
||||
#define BOARD_TYPE "SAMD SEEEDUINO_ZERO"
|
||||
#elif defined(SEEEDUINO_LORAWAN)
|
||||
#define BOARD_TYPE "SAMD SEEEDUINO_LORAWAN"
|
||||
#elif defined(SEEED_GROVE_UI_WIRELESS)
|
||||
#define BOARD_TYPE "SAMD SEEED_GROVE_UI_WIRELESS"
|
||||
#elif defined(__SAMD21E18A__)
|
||||
#define BOARD_TYPE "SAMD21E18A"
|
||||
#elif defined(__SAMD21G18A__)
|
||||
#define BOARD_TYPE "SAMD21G18A"
|
||||
#elif defined(__SAMD51G19A__)
|
||||
#define BOARD_TYPE "SAMD51G19A"
|
||||
#elif defined(__SAMD51J19A__)
|
||||
#define BOARD_TYPE "SAMD51J19A"
|
||||
#elif defined(__SAMD51P19A__)
|
||||
#define BOARD_TYPE "__SAMD51P19A__"
|
||||
#elif defined(__SAMD51J20A__)
|
||||
#define BOARD_TYPE "SAMD51J20A"
|
||||
#elif defined(__SAM3X8E__)
|
||||
#define BOARD_TYPE "SAM3X8E"
|
||||
#elif defined(__CPU_ARC__)
|
||||
#define BOARD_TYPE "CPU_ARC"
|
||||
#elif defined(__SAMD51__)
|
||||
#define BOARD_TYPE "SAMD51"
|
||||
#else
|
||||
#define BOARD_TYPE "SAMD Unknown"
|
||||
#endif
|
||||
|
||||
#elif defined(WIFI_USE_STM32)
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
// For STM32
|
||||
#if defined(ARDUINO_NUCLEO_F767ZI)
|
||||
#warning Nucleo-144 NUCLEO_F767ZI board selected, using HardwareSerial Serial1 @ pin D0/RX and D1/TX
|
||||
// RX TX
|
||||
HardwareSerial Serial1(D0, D1);
|
||||
#elif defined(ARDUINO_NUCLEO_L053R8)
|
||||
#warning Nucleo-64 NUCLEO_L053R8 board selected, using HardwareSerial Serial1 @ pin D0/RX and D1/TX
|
||||
// RX TX
|
||||
HardwareSerial Serial1(D0, D1); // (PA3, PA2);
|
||||
#endif
|
||||
|
||||
#warning EspSerial using SERIAL_PORT_HARDWARE, can be Serial or Serial1. See your board variant.h
|
||||
#define EspSerial SERIAL_PORT_HARDWARE //Serial1
|
||||
#endif
|
||||
|
||||
#if defined(STM32F0)
|
||||
#warning STM32F0 board selected
|
||||
#define BOARD_TYPE "STM32F0"
|
||||
#elif defined(STM32F1)
|
||||
#warning STM32F1 board selected
|
||||
#define BOARD_TYPE "STM32F1"
|
||||
#elif defined(STM32F2)
|
||||
#warning STM32F2 board selected
|
||||
#define BOARD_TYPE "STM32F2"
|
||||
#elif defined(STM32F3)
|
||||
#warning STM32F3 board selected
|
||||
#define BOARD_TYPE "STM32F3"
|
||||
#elif defined(STM32F4)
|
||||
#warning STM32F4 board selected
|
||||
#define BOARD_TYPE "STM32F4"
|
||||
#elif defined(STM32F7)
|
||||
#warning STM32F7 board selected
|
||||
#define BOARD_TYPE "STM32F7"
|
||||
#elif defined(STM32L0)
|
||||
#warning STM32L0 board selected
|
||||
#define BOARD_TYPE "STM32L0"
|
||||
#elif defined(STM32L1)
|
||||
#warning STM32L1 board selected
|
||||
#define BOARD_TYPE "STM32L1"
|
||||
#elif defined(STM32L4)
|
||||
#warning STM32L4 board selected
|
||||
#define BOARD_TYPE "STM32L4"
|
||||
#elif defined(STM32H7)
|
||||
#warning STM32H7 board selected
|
||||
#define BOARD_TYPE "STM32H7"
|
||||
#elif defined(STM32G0)
|
||||
#warning STM32G0 board selected
|
||||
#define BOARD_TYPE "STM32G0"
|
||||
#elif defined(STM32G4)
|
||||
#warning STM32G4 board selected
|
||||
#define BOARD_TYPE "STM32G4"
|
||||
#elif defined(STM32WB)
|
||||
#warning STM32WB board selected
|
||||
#define BOARD_TYPE "STM32WB"
|
||||
#elif defined(STM32MP1)
|
||||
#warning STM32MP1 board selected
|
||||
#define BOARD_TYPE "STM32MP1"
|
||||
#else
|
||||
#warning STM32 unknown board selected
|
||||
#define BOARD_TYPE "STM32 Unknown"
|
||||
#endif
|
||||
|
||||
#elif (ESP8266)
|
||||
#warning ESP8266 board selected
|
||||
#define BOARD_TYPE ARDUINO_BOARD
|
||||
|
||||
#elif (ESP32)
|
||||
#warning ESP32 board selected
|
||||
#define BOARD_TYPE ARDUINO_BOARD
|
||||
|
||||
#elif defined(WIFI_USE_RP2040) && !defined(ARDUINO_ARCH_MBED)
|
||||
|
||||
// For RP2040
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#elif defined(WIFI_USE_RP2040) && defined(ARDUINO_ARCH_MBED)
|
||||
|
||||
#warning Using ARDUINO_ARCH_MBED
|
||||
|
||||
// For MBED RP2040
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_RASPBERRY_PI_PICO) || \
|
||||
defined(ARDUINO_GENERIC_RP2040) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) )
|
||||
// Only undef known BOARD_NAME to use better one
|
||||
#undef BOARD_NAME
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_RASPBERRY_PI_PICO)
|
||||
#define BOARD_NAME "MBED RASPBERRY_PI_PICO"
|
||||
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
|
||||
#define BOARD_NAME "MBED ADAFRUIT_FEATHER_RP2040"
|
||||
#elif defined(ARDUINO_GENERIC_RP2040)
|
||||
#define BOARD_NAME "MBED GENERIC_RP2040"
|
||||
#elif defined(ARDUINO_NANO_RP2040_CONNECT)
|
||||
#define BOARD_NAME "MBED NANO_RP2040_CONNECT"
|
||||
#else
|
||||
// Use default BOARD_NAME if exists
|
||||
#if !defined(BOARD_NAME)
|
||||
#define BOARD_NAME "MBED Unknown RP2040"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
// For Mega
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#define BOARD_TYPE "AVR Mega"
|
||||
#endif
|
||||
|
||||
#ifndef BOARD_NAME
|
||||
#define BOARD_NAME BOARD_TYPE
|
||||
#endif
|
||||
|
||||
#endif //defines_h
|
583
ESP32QRCodeReader_Page/ESP32QRCodeReader_Page.ino
Normal file
583
ESP32QRCodeReader_Page/ESP32QRCodeReader_Page.ino
Normal file
@ -0,0 +1,583 @@
|
||||
/*
|
||||
ESP32-CAM QR code Reader
|
||||
Author : ChungYi Fu (Kaohsiung, Taiwan) 2021-8-13 20:00
|
||||
https://www.facebook.com/francefu
|
||||
|
||||
Refer to the code
|
||||
https://github.com/alvarowolfx/ESP32QRCodeReader
|
||||
|
||||
自訂指令格式 http://192.168.xxx.xxx/control?cmd=P1;P2;P3;P4;P5;P6;P7;P8;P9
|
||||
|
||||
http://192.168.xxx.xxx/?ip //取得APIP, STAIP
|
||||
http://192.168.xxx.xxx/?mac //取得MAC位址
|
||||
http://192.168.xxx.xxx/?digitalwrite=pin;value //數位輸出
|
||||
http://192.168.xxx.xxx/?analogwrite=pin;value //類比輸出
|
||||
http://192.168.xxx.xxx/?digitalread=pin //數位讀取
|
||||
http://192.168.xxx.xxx/?analogread=pin //類比讀取
|
||||
http://192.168.xxx.xxx/?touchread=pin //觸碰讀取
|
||||
http://192.168.xxx.xxx/?restart //重啟電源
|
||||
http://192.168.xxx.xxx/?flash=value //閃光燈 value= 0~255
|
||||
http://192.168.xxx.xxx/?servo=pin;value //伺服馬達 value= 0~180
|
||||
http://192.168.xxx.xxx/?relay=pin;value //繼電器 value = 0, 1
|
||||
http://192.168.xxx.xxx/?uart=value //序列埠
|
||||
*/
|
||||
|
||||
//輸入WIFI連線帳號密碼
|
||||
const char* ssid = "cpsNUCwifi";
|
||||
const char* password = "ips999CPS";
|
||||
|
||||
//輸入AP端連線帳號密碼 http://192.168.4.1
|
||||
const char* apssid = "esp32-cam";
|
||||
const char* appassword = "12345678"; //AP密碼至少要8個字元以上
|
||||
|
||||
String Feedback=""; //回傳客戶端訊息
|
||||
//指令參數值
|
||||
String Command="",cmd="",P1="",P2="",P3="",P4="",P5="",P6="",P7="",P8="",P9="";
|
||||
//指令拆解狀態值
|
||||
byte ReceiveState=0,cmdState=1,strState=1,questionstate=0,equalstate=0,semicolonstate=0;
|
||||
|
||||
#include <WiFi.h>
|
||||
#include "esp_camera.h" //視訊函式
|
||||
#include "soc/soc.h" //用於電源不穩不重開機
|
||||
#include "soc/rtc_cntl_reg.h" //用於電源不穩不重開機
|
||||
#include "quirc.h"
|
||||
|
||||
TaskHandle_t Task;
|
||||
|
||||
//ESP32-CAM 安信可模組腳位設定
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 0
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 21
|
||||
#define Y4_GPIO_NUM 19
|
||||
#define Y3_GPIO_NUM 18
|
||||
#define Y2_GPIO_NUM 5
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
struct QRCodeData
|
||||
{
|
||||
bool valid;
|
||||
int dataType;
|
||||
uint8_t payload[1024];
|
||||
int payloadLen;
|
||||
};
|
||||
|
||||
struct quirc *q = NULL;
|
||||
uint8_t *image = NULL;
|
||||
camera_fb_t * fb = NULL;
|
||||
struct quirc_code code;
|
||||
struct quirc_data data;
|
||||
quirc_decode_error_t err;
|
||||
struct QRCodeData qrCodeData;
|
||||
String QRCodeResult = "";
|
||||
|
||||
WiFiServer server(80);
|
||||
WiFiClient client;
|
||||
|
||||
camera_config_t config;
|
||||
|
||||
void setup() {
|
||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //關閉電源不穩就重開機的設定
|
||||
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true); //開啟診斷輸出
|
||||
Serial.println();
|
||||
|
||||
//視訊組態設定 https://github.com/espressif/esp32-camera/blob/master/driver/include/esp_camera.h
|
||||
config.ledc_channel = LEDC_CHANNEL_0;
|
||||
config.ledc_timer = LEDC_TIMER_0;
|
||||
config.pin_d0 = Y2_GPIO_NUM;
|
||||
config.pin_d1 = Y3_GPIO_NUM;
|
||||
config.pin_d2 = Y4_GPIO_NUM;
|
||||
config.pin_d3 = Y5_GPIO_NUM;
|
||||
config.pin_d4 = Y6_GPIO_NUM;
|
||||
config.pin_d5 = Y7_GPIO_NUM;
|
||||
config.pin_d6 = Y8_GPIO_NUM;
|
||||
config.pin_d7 = Y9_GPIO_NUM;
|
||||
config.pin_xclk = XCLK_GPIO_NUM;
|
||||
config.pin_pclk = PCLK_GPIO_NUM;
|
||||
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||
config.pin_href = HREF_GPIO_NUM;
|
||||
config.pin_sscb_sda = SIOD_GPIO_NUM;
|
||||
config.pin_sscb_scl = SIOC_GPIO_NUM;
|
||||
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||
config.pin_reset = RESET_GPIO_NUM;
|
||||
config.xclk_freq_hz = 10000000;
|
||||
config.pixel_format = PIXFORMAT_GRAYSCALE;
|
||||
config.frame_size = FRAMESIZE_QVGA;
|
||||
config.jpeg_quality = 15;
|
||||
config.fb_count = 1;
|
||||
|
||||
//視訊初始化
|
||||
esp_err_t err = esp_camera_init(&config);
|
||||
if (err != ESP_OK) {
|
||||
Serial.printf("Camera init failed with error 0x%x", err);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
s->set_framesize(s, FRAMESIZE_QVGA);
|
||||
|
||||
//s->set_vflip(s, 1); //垂直翻轉
|
||||
//s->set_hmirror(s, 1); //水平鏡像
|
||||
|
||||
//閃光燈(GPIO4)
|
||||
ledcAttachPin(4, 4);
|
||||
ledcSetup(4, 5000, 8);
|
||||
|
||||
WiFi.mode(WIFI_AP_STA); //其他模式 WiFi.mode(WIFI_AP); WiFi.mode(WIFI_STA);
|
||||
|
||||
//指定Client端靜態IP
|
||||
//WiFi.config(IPAddress(192, 168, 201, 100), IPAddress(192, 168, 201, 2), IPAddress(255, 255, 255, 0));
|
||||
|
||||
for (int i=0;i<2;i++) {
|
||||
WiFi.begin(ssid, password); //執行網路連線
|
||||
|
||||
delay(1000);
|
||||
Serial.println("");
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(ssid);
|
||||
|
||||
long int StartTime=millis();
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
if ((StartTime+5000) < millis()) break; //等待10秒連線
|
||||
}
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED) { //若連線成功
|
||||
WiFi.softAP((WiFi.localIP().toString()+"_"+(String)apssid).c_str(), appassword); //設定SSID顯示客戶端IP
|
||||
Serial.println("");
|
||||
Serial.println("STAIP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
Serial.println("");
|
||||
|
||||
for (int i=0;i<5;i++) { //若連上WIFI設定閃光燈快速閃爍
|
||||
ledcWrite(4,10);
|
||||
delay(200);
|
||||
ledcWrite(4,0);
|
||||
delay(200);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED) { //若連線失敗
|
||||
WiFi.softAP((WiFi.softAPIP().toString()+"_"+(String)apssid).c_str(), appassword);
|
||||
|
||||
for (int i=0;i<2;i++) { //若連不上WIFI設定閃光燈慢速閃爍
|
||||
ledcWrite(4,10);
|
||||
delay(1000);
|
||||
ledcWrite(4,0);
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
//指定AP端IP
|
||||
//WiFi.softAPConfig(IPAddress(192, 168, 4, 1), IPAddress(192, 168, 4, 1), IPAddress(255, 255, 255, 0));
|
||||
Serial.println("");
|
||||
Serial.println("APIP address: ");
|
||||
Serial.println(WiFi.softAPIP());
|
||||
Serial.println("");
|
||||
|
||||
//設定閃光燈為低電位
|
||||
pinMode(4, OUTPUT);
|
||||
digitalWrite(4, LOW);
|
||||
|
||||
server.begin();
|
||||
|
||||
xTaskCreatePinnedToCore(
|
||||
QRCodeReader, /* Task function. */
|
||||
"Task", /* name of task. */
|
||||
10000, /* Stack size of task */
|
||||
NULL, /* parameter of the task */
|
||||
1, /* priority of the task */
|
||||
&Task, /* Task handle to keep track of created task */
|
||||
0); /* pin task to core 0 */
|
||||
|
||||
Serial.print("listenConnection running on core ");
|
||||
Serial.println(xPortGetCoreID());
|
||||
}
|
||||
|
||||
void loop() {
|
||||
listenConnection();
|
||||
}
|
||||
|
||||
void QRCodeReader( void * pvParameters ){
|
||||
Serial.print("QRCodeReader running on core ");
|
||||
Serial.println(xPortGetCoreID());
|
||||
|
||||
while(1){
|
||||
q = quirc_new();
|
||||
if (q == NULL){
|
||||
Serial.print("can't create quirc object\r\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
fb = esp_camera_fb_get();
|
||||
if (!fb)
|
||||
{
|
||||
Serial.println("Camera capture failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
//Serial.printf("quirc_begin\r\n");
|
||||
quirc_resize(q, fb->width, fb->height);
|
||||
image = quirc_begin(q, NULL, NULL);
|
||||
//Serial.printf("Frame w h len: %d, %d, %d \r\n", fb->width, fb->height, fb->len);
|
||||
memcpy(image, fb->buf, fb->len);
|
||||
quirc_end(q);
|
||||
//Serial.printf("quirc_end\r\n");
|
||||
|
||||
int count = quirc_count(q);
|
||||
if (count > 0) {
|
||||
Serial.println(count);
|
||||
quirc_extract(q, 0, &code);
|
||||
err = quirc_decode(&code, &data);
|
||||
|
||||
if (err){
|
||||
Serial.println("Decoding FAILED");
|
||||
QRCodeResult = "Decoding FAILED";
|
||||
} else {
|
||||
Serial.printf("Decoding successful:\n");
|
||||
dumpData(&data);
|
||||
/*
|
||||
qrCodeData.dataType = data.data_type;
|
||||
for (int j = 0; j < data.payload_len; j++)
|
||||
{
|
||||
qrCodeData.payload[j] = data.payload[j];
|
||||
}
|
||||
qrCodeData.valid = true;
|
||||
qrCodeData.payload[data.payload_len] = '\0';
|
||||
qrCodeData.payloadLen = data.payload_len;
|
||||
*/
|
||||
//vTaskDelay(3000/portTICK_RATE_MS);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
esp_camera_fb_return(fb);
|
||||
fb = NULL;
|
||||
image = NULL;
|
||||
quirc_destroy(q);
|
||||
}
|
||||
}
|
||||
|
||||
void dumpData(const struct quirc_data *data)
|
||||
{
|
||||
Serial.printf("Version: %d\n", data->version);
|
||||
Serial.printf("ECC level: %c\n", "MLHQ"[data->ecc_level]);
|
||||
Serial.printf("Mask: %d\n", data->mask);
|
||||
Serial.printf("Length: %d\n", data->payload_len);
|
||||
Serial.printf("Payload: %s\n", data->payload);
|
||||
|
||||
QRCodeResult = (const char *)data->payload;
|
||||
}
|
||||
|
||||
//執行自訂指令
|
||||
void ExecuteCommand() {
|
||||
//Serial.println("");
|
||||
//Serial.println("Command: "+Command);
|
||||
if (cmd!="getstill") {
|
||||
Serial.println("cmd= "+cmd+" ,P1= "+P1+" ,P2= "+P2+" ,P3= "+P3+" ,P4= "+P4+" ,P5= "+P5+" ,P6= "+P6+" ,P7= "+P7+" ,P8= "+P8+" ,P9= "+P9);
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
//自訂指令區塊 http://192.168.xxx.xxx?cmd=P1;P2;P3;P4;P5;P6;P7;P8;P9
|
||||
if (cmd=="your cmd") {
|
||||
// You can do anything
|
||||
// Feedback="<font color=\"red\">Hello World</font>"; //可為一般文字或HTML語法
|
||||
}
|
||||
else if (cmd=="ip") { //查詢APIP, STAIP
|
||||
Feedback="AP IP: "+WiFi.softAPIP().toString();
|
||||
Feedback+="<br>";
|
||||
Feedback+="STA IP: "+WiFi.localIP().toString();
|
||||
}
|
||||
else if (cmd=="mac") { //查詢MAC位址
|
||||
Feedback="STA MAC: "+WiFi.macAddress();
|
||||
}
|
||||
else if (cmd=="restart") { //重設WIFI連線
|
||||
ESP.restart();
|
||||
}
|
||||
else if (cmd=="digitalwrite") { //數位輸出
|
||||
ledcDetachPin(P1.toInt());
|
||||
pinMode(P1.toInt(), OUTPUT);
|
||||
digitalWrite(P1.toInt(), P2.toInt());
|
||||
}
|
||||
else if (cmd=="digitalread") { //數位輸入
|
||||
Feedback=String(digitalRead(P1.toInt()));
|
||||
}
|
||||
else if (cmd=="analogwrite") { //類比輸出
|
||||
if (P1=="4") {
|
||||
ledcAttachPin(4, 4);
|
||||
ledcSetup(4, 5000, 8);
|
||||
ledcWrite(4,P2.toInt());
|
||||
}
|
||||
else {
|
||||
ledcAttachPin(P1.toInt(), 9);
|
||||
ledcSetup(9, 5000, 8);
|
||||
ledcWrite(9,P2.toInt());
|
||||
}
|
||||
}
|
||||
else if (cmd=="analogread") { //類比讀取
|
||||
Feedback=String(analogRead(P1.toInt()));
|
||||
}
|
||||
else if (cmd=="touchread") { //觸碰讀取
|
||||
Feedback=String(touchRead(P1.toInt()));
|
||||
}
|
||||
else if (cmd=="framesize") { //解析度
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int val = P1.toInt();
|
||||
s->set_framesize(s, (framesize_t)val);
|
||||
}
|
||||
else if (cmd=="quality") { //畫質
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int val = P1.toInt();
|
||||
s->set_quality(s, val);
|
||||
}
|
||||
else if (cmd=="contrast") { //對比
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int val = P1.toInt();
|
||||
s->set_contrast(s, val);
|
||||
}
|
||||
else if (cmd=="brightness") { //亮度
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int val = P1.toInt();
|
||||
s->set_brightness(s, val);
|
||||
}
|
||||
else if (cmd=="hmirror") { //水平鏡像
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int val = P1.toInt();
|
||||
s->set_hmirror(s, val);
|
||||
}
|
||||
else if (cmd=="vflip") { //垂直翻轉
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int val = P1.toInt();
|
||||
s->set_vflip(s, val);
|
||||
}
|
||||
else if (cmd=="serial") { //序列埠
|
||||
Serial.print(P1);
|
||||
}
|
||||
else if (cmd=="restart") { //重啟電源
|
||||
ESP.restart();
|
||||
}
|
||||
else if (cmd=="flash") { //閃光燈
|
||||
ledcAttachPin(4, 4);
|
||||
ledcSetup(4, 5000, 8);
|
||||
int val = P1.toInt();
|
||||
ledcWrite(4,val);
|
||||
}
|
||||
else if(cmd=="servo") { //伺服馬達 (0-180)
|
||||
ledcAttachPin(P1.toInt(), 3);
|
||||
ledcSetup(3, 50, 16);
|
||||
|
||||
int val = 7864-P2.toInt()*34.59;
|
||||
if (val > 7864)
|
||||
val = 7864;
|
||||
else if (val < 1638)
|
||||
val = 1638;
|
||||
ledcWrite(3, val);
|
||||
}
|
||||
else if (cmd=="relay") { //繼電器
|
||||
pinMode(P1.toInt(), OUTPUT);
|
||||
digitalWrite(13, P2.toInt());
|
||||
}
|
||||
else {
|
||||
Feedback="Command is not defined.";
|
||||
}
|
||||
|
||||
if (Feedback=="") Feedback=Command;
|
||||
}
|
||||
|
||||
|
||||
//自訂網頁首頁管理介面
|
||||
static const char PROGMEM INDEX_HTML[] = R"rawliteral(
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" width="320" height="240"></canvas><br>
|
||||
Flash<input type="range" id="flash" min="0" max="255" value="0">
|
||||
<input type="button" value="Get Still" onclick="getStill();"><br>
|
||||
<div id="result" style="color:red"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
var flash = document.getElementById('flash');
|
||||
var result = document.getElementById('result');
|
||||
|
||||
flash.onchange = function() {
|
||||
var query = document.location.origin+"/?flash="+flash.value;
|
||||
fetch(query);
|
||||
}
|
||||
|
||||
function getStill() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/?getstill", true);
|
||||
xhr.responseType = "arraybuffer";
|
||||
|
||||
xhr.onload = function (oEvent) {
|
||||
var arrayBuffer = xhr.response; // Note: not xhr.responseText
|
||||
if (arrayBuffer) {
|
||||
var byteArray = new Uint8Array(arrayBuffer);
|
||||
var imgData=context.getImageData(0,0,canvas.width,canvas.height);
|
||||
var val = 0;
|
||||
for (var i=0;i<imgData.data.length;i+=4) {
|
||||
val = parseInt(byteArray[i/4], 10);
|
||||
imgData.data[i]=val;
|
||||
imgData.data[i+1]=val;
|
||||
imgData.data[i+2]=val;
|
||||
imgData.data[i+3]=255;
|
||||
}
|
||||
context.putImageData(imgData,0,0);
|
||||
setTimeout(function(){getStill();}, 100);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(null);
|
||||
}
|
||||
</script>
|
||||
)rawliteral";
|
||||
|
||||
void listenConnection() {
|
||||
Feedback="";Command="";cmd="";P1="";P2="";P3="";P4="";P5="";P6="";P7="";P8="";P9="";
|
||||
ReceiveState=0,cmdState=1,strState=1,questionstate=0,equalstate=0,semicolonstate=0;
|
||||
|
||||
client = server.available();
|
||||
|
||||
if (client) {
|
||||
String currentLine = "";
|
||||
|
||||
while (client.connected()) {
|
||||
if (client.available()) {
|
||||
char c = client.read();
|
||||
getCommand(c); //將緩衝區取得的字元拆解出指令參數
|
||||
if (c == '\n') {
|
||||
if (currentLine.length() == 0) {
|
||||
if (cmd=="getstill") {
|
||||
getStill();
|
||||
} else {
|
||||
mainPage();
|
||||
}
|
||||
Feedback="";
|
||||
break;
|
||||
} else {
|
||||
currentLine = "";
|
||||
}
|
||||
} else if (c != '\r') {
|
||||
currentLine += c;
|
||||
}
|
||||
|
||||
if ((currentLine.indexOf("?")!=-1)&&(currentLine.indexOf(" HTTP")!=-1)) {
|
||||
if (Command.indexOf("stop")!=-1) { //若指令中含關鍵字stop立即斷線 -> http://192.168.xxx.xxx?cmd=aaa;bbb;ccc;stop
|
||||
client.println();
|
||||
client.println();
|
||||
client.stop();
|
||||
}
|
||||
currentLine="";
|
||||
Feedback="";
|
||||
ExecuteCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
delay(1);
|
||||
client.stop();
|
||||
}
|
||||
}
|
||||
|
||||
void mainPage() {
|
||||
//回傳HTML首頁或Feedback
|
||||
client.println("HTTP/1.1 200 OK");
|
||||
client.println("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
|
||||
client.println("Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS");
|
||||
client.println("Content-Type: text/html; charset=utf-8");
|
||||
client.println("Access-Control-Allow-Origin: *");
|
||||
client.println("Connection: close");
|
||||
client.println();
|
||||
|
||||
String Data="";
|
||||
if (cmd!="")
|
||||
Data = Feedback;
|
||||
else {
|
||||
Data = String((const char *)INDEX_HTML);
|
||||
}
|
||||
int Index;
|
||||
for (Index = 0; Index < Data.length(); Index = Index+1024) {
|
||||
client.print(Data.substring(Index, Index+1024));
|
||||
}
|
||||
}
|
||||
|
||||
void getStill() {
|
||||
camera_fb_t * fb = NULL;
|
||||
fb = esp_camera_fb_get();
|
||||
if(!fb) {
|
||||
Serial.println("Camera capture failed");
|
||||
return;
|
||||
}
|
||||
uint8_t *fbBuf = fb->buf;
|
||||
size_t fbLen = fb->len;
|
||||
|
||||
client.println("HTTP/1.1 200 OK");
|
||||
client.println("Access-Control-Allow-Origin: *");
|
||||
client.println("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
|
||||
client.println("Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS");
|
||||
client.println("Content-Type: application/octet-stream");
|
||||
client.println();
|
||||
|
||||
for (size_t n=0;n<fbLen;n=n+1024) {
|
||||
if (n+1024<fbLen) {
|
||||
client.write(fbBuf, 1024);
|
||||
fbBuf += 1024;
|
||||
}
|
||||
else if (fbLen%1024>0) {
|
||||
size_t remainder = fbLen%1024;
|
||||
client.write(fbBuf, remainder);
|
||||
}
|
||||
}
|
||||
esp_camera_fb_return(fb);
|
||||
|
||||
pinMode(4, OUTPUT);
|
||||
digitalWrite(4, LOW);
|
||||
}
|
||||
|
||||
//拆解命令字串置入變數
|
||||
void getCommand(char c) {
|
||||
if (c=='?') ReceiveState=1;
|
||||
if ((c==' ')||(c=='\r')||(c=='\n')) ReceiveState=0;
|
||||
|
||||
if (ReceiveState==1)
|
||||
{
|
||||
Command=Command+String(c);
|
||||
|
||||
if (c=='=') cmdState=0;
|
||||
if (c==';') strState++;
|
||||
|
||||
if ((cmdState==1)&&((c!='?')||(questionstate==1))) cmd=cmd+String(c);
|
||||
if ((cmdState==0)&&(strState==1)&&((c!='=')||(equalstate==1))) P1=P1+String(c);
|
||||
if ((cmdState==0)&&(strState==2)&&(c!=';')) P2=P2+String(c);
|
||||
if ((cmdState==0)&&(strState==3)&&(c!=';')) P3=P3+String(c);
|
||||
if ((cmdState==0)&&(strState==4)&&(c!=';')) P4=P4+String(c);
|
||||
if ((cmdState==0)&&(strState==5)&&(c!=';')) P5=P5+String(c);
|
||||
if ((cmdState==0)&&(strState==6)&&(c!=';')) P6=P6+String(c);
|
||||
if ((cmdState==0)&&(strState==7)&&(c!=';')) P7=P7+String(c);
|
||||
if ((cmdState==0)&&(strState==8)&&(c!=';')) P8=P8+String(c);
|
||||
if ((cmdState==0)&&(strState>=9)&&((c!=';')||(semicolonstate==1))) P9=P9+String(c);
|
||||
|
||||
if (c=='?') questionstate=1;
|
||||
if (c=='=') equalstate=1;
|
||||
if ((strState>=9)&&(c==';')) semicolonstate=1;
|
||||
}
|
||||
}
|
16
ESP32QRCodeReader_Page/LICENSE
Normal file
16
ESP32QRCodeReader_Page/LICENSE
Normal file
@ -0,0 +1,16 @@
|
||||
quirc -- QR-code recognition library
|
||||
Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all
|
||||
copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
193
ESP32QRCodeReader_Page/README.md
Normal file
193
ESP32QRCodeReader_Page/README.md
Normal file
@ -0,0 +1,193 @@
|
||||
Quirc
|
||||
=====
|
||||
|
||||
QR codes are a type of high-density matrix barcodes, and quirc is a library for
|
||||
extracting and decoding them from images. It has several features which make it
|
||||
a good choice for this purpose:
|
||||
|
||||
* It is fast enough to be used with realtime video: extracting and decoding
|
||||
from VGA frame takes about 50 ms on a modern x86 core.
|
||||
|
||||
* It has a robust and tolerant recognition algorithm. It can correctly
|
||||
recognise and decode QR codes which are rotated and/or oblique to the camera.
|
||||
It can also distinguish and decode multiple codes within the same image.
|
||||
|
||||
* It is easy to use, with a simple API described in a single commented header
|
||||
file (see below for an overview).
|
||||
|
||||
* It is small and easily embeddable, with no dependencies other than standard C
|
||||
functions.
|
||||
|
||||
* It has a very small memory footprint: one byte per image pixel, plus a few kB
|
||||
per decoder object.
|
||||
|
||||
* It uses no global mutable state, and is safe to use in a multithreaded
|
||||
application.
|
||||
|
||||
* BSD-licensed, with almost no restrictions regarding use and/or modification.
|
||||
|
||||
The distribution comes with, in addition to the library, several test programs.
|
||||
While the core library is very portable, these programs have some additional
|
||||
dependencies. All of them require libjpeg, and two (`quirc-demo` and `inspect`)
|
||||
require SDL. The camera demos use Linux-specific APIs:
|
||||
|
||||
### quirc-demo
|
||||
|
||||
This is an real-time demo which requires a camera and a graphical display. The
|
||||
video stream is displayed on screen as it's received, and any QR codes
|
||||
recognised are highlighted in the image, with the decoded information both
|
||||
displayed on the image and printed on stdout.
|
||||
|
||||
### quirc-scanner
|
||||
|
||||
This program turns your camera into a barcode scanner. It's almost the same as
|
||||
the `demo` application, but it doesn't display the video stream, and thus
|
||||
doesn't require a graphical display.
|
||||
|
||||
### qrtest
|
||||
|
||||
This test is used to evaluate the performance of library. Given a directory
|
||||
tree containing a bunch of JPEG images, it will attempt to locate and decode QR
|
||||
codes in each image. Speed and success statistics are collected and printed on
|
||||
stdout.
|
||||
|
||||
### inspect
|
||||
|
||||
This test is used for debugging. Given a single JPEG image, it will display a
|
||||
diagram showing the internal state of the decoder as well as printing
|
||||
additional information on stdout.
|
||||
|
||||
Installation
|
||||
------------
|
||||
To build the library and associated demos/tests, type `make`. If you need to
|
||||
decode "large" image files build with `CFLAGS="-DQUIRC_MAX_REGIONS=65534" make`
|
||||
instead. Note that this will increase the memory usage, it is discouraged for
|
||||
low resource devices (i.e. embedded).
|
||||
|
||||
Type `make install` to install the library, header file and camera demos.
|
||||
|
||||
You can specify one or several of the following targets if you don't want, or
|
||||
are unable to build everything:
|
||||
|
||||
* libquirc.a
|
||||
* libquirc.so
|
||||
* qrtest
|
||||
* inspect
|
||||
* quirc-scanner
|
||||
* quirc-demo
|
||||
|
||||
Library use
|
||||
-----------
|
||||
All of the library's functionality is exposed through a single header file,
|
||||
which you should include:
|
||||
|
||||
```C
|
||||
#include <quirc.h>
|
||||
```
|
||||
|
||||
To decode images, you'll need to instantiate a `struct quirc` object, which is
|
||||
done with the `quirc_new` function. Later, when you no longer need to decode
|
||||
anything, you should release the allocated memory with `quirc_destroy`:
|
||||
|
||||
```C
|
||||
struct quirc *qr;
|
||||
|
||||
qr = quirc_new();
|
||||
if (!qr) {
|
||||
perror("Failed to allocate memory");
|
||||
abort();
|
||||
}
|
||||
|
||||
/* ... */
|
||||
|
||||
quirc_destroy(qr);
|
||||
```
|
||||
|
||||
Having obtained a decoder object, you need to set the image size that you'll be
|
||||
working with, which is done using `quirc_resize`:
|
||||
|
||||
```C
|
||||
if (quirc_resize(qr, 640, 480) < 0) {
|
||||
perror("Failed to allocate video memory");
|
||||
abort();
|
||||
}
|
||||
```
|
||||
|
||||
`quirc_resize` and `quirc_new` are the only library functions which allocate
|
||||
memory. If you plan to process a series of frames (or a video stream), you
|
||||
probably want to allocate and size a single decoder and hold onto it to process
|
||||
each frame.
|
||||
|
||||
Processing frames is done in two stages. The first stage is an
|
||||
image-recognition stage called identification, which takes a grayscale image
|
||||
and searches for QR codes. Using `quirc_begin` and `quirc_end`, you can feed a
|
||||
grayscale image directly into the buffer that `quirc` uses for image
|
||||
processing:
|
||||
|
||||
```C
|
||||
uint8_t *image;
|
||||
int w, h;
|
||||
|
||||
image = quirc_begin(qr, &w, &h);
|
||||
|
||||
/* Fill out the image buffer here.
|
||||
* image is a pointer to a w*h bytes.
|
||||
* One byte per pixel, w pixels per line, h lines in the buffer.
|
||||
*/
|
||||
|
||||
quirc_end(qr);
|
||||
```
|
||||
|
||||
Note that `quirc_begin` simply returns a pointer to a previously allocated
|
||||
buffer. The buffer will contain uninitialized data. After the call to
|
||||
`quirc_end`, the decoder holds a list of detected QR codes which can be queried
|
||||
via `quirc_count` and `quirc_extract`.
|
||||
|
||||
At this point, the second stage of processing occurs -- decoding. This is done
|
||||
via the call to `quirc_decode`, which is not associated with a decoder object.
|
||||
|
||||
```C
|
||||
int num_codes;
|
||||
int i;
|
||||
|
||||
/* We've previously fed an image to the decoder via
|
||||
* quirc_begin/quirc_end.
|
||||
*/
|
||||
|
||||
num_codes = quirc_count(qr);
|
||||
for (i = 0; i < num_codes; i++) {
|
||||
struct quirc_code code;
|
||||
struct quirc_data data;
|
||||
quirc_decode_error_t err;
|
||||
|
||||
quirc_extract(qr, i, &code);
|
||||
|
||||
/* Decoding stage */
|
||||
err = quirc_decode(&code, &data);
|
||||
if (err)
|
||||
printf("DECODE FAILED: %s\n", quirc_strerror(err));
|
||||
else
|
||||
printf("Data: %s\n", data.payload);
|
||||
}
|
||||
```
|
||||
|
||||
`quirc_code` and `quirc_data` are flat structures which don't need to be
|
||||
initialized or freed after use.
|
||||
|
||||
Copyright
|
||||
---------
|
||||
Copyright (C) 2010-2012 Daniel Beer <<dlbeer@gmail.com>>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all
|
||||
copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
85
ESP32QRCodeReader_Page/collections.c
Normal file
85
ESP32QRCodeReader_Page/collections.c
Normal file
@ -0,0 +1,85 @@
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2017 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "collections.h"
|
||||
#define CHAR_BITS (sizeof(char) * 8)
|
||||
#define CHAR_MASK (CHAR_BITS - 1)
|
||||
#define CHAR_SHIFT IM_LOG2(CHAR_MASK)
|
||||
|
||||
//////////
|
||||
// lifo //
|
||||
//////////
|
||||
|
||||
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len)
|
||||
{
|
||||
ptr->len = 0;
|
||||
ptr->size = size;
|
||||
ptr->data_len = data_len;
|
||||
ptr->data = (char *)ps_malloc(size * data_len);
|
||||
}
|
||||
|
||||
void lifo_alloc_all(lifo_t *ptr, size_t *size, size_t data_len)
|
||||
{
|
||||
ptr->data = (char *)ps_malloc(255);
|
||||
ptr->data_len = data_len;
|
||||
ptr->size = 255 / data_len;
|
||||
ptr->len = 0;
|
||||
*size = ptr->size;
|
||||
}
|
||||
|
||||
void lifo_free(lifo_t *ptr)
|
||||
{
|
||||
if (ptr->data)
|
||||
{
|
||||
free(ptr->data);
|
||||
}
|
||||
}
|
||||
|
||||
void lifo_clear(lifo_t *ptr)
|
||||
{
|
||||
ptr->len = 0;
|
||||
}
|
||||
|
||||
size_t lifo_size(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len;
|
||||
}
|
||||
|
||||
bool lifo_is_not_empty(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len;
|
||||
}
|
||||
|
||||
bool lifo_is_not_full(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len != ptr->size;
|
||||
}
|
||||
|
||||
void lifo_enqueue(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(ptr->data + (ptr->len * ptr->data_len), data, ptr->data_len);
|
||||
|
||||
ptr->len += 1;
|
||||
}
|
||||
|
||||
void lifo_dequeue(lifo_t *ptr, void *data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
memcpy(data, ptr->data + ((ptr->len - 1) * ptr->data_len), ptr->data_len);
|
||||
}
|
||||
|
||||
ptr->len -= 1;
|
||||
}
|
||||
|
||||
void lifo_poke(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(ptr->data + (ptr->len * ptr->data_len), data, ptr->data_len);
|
||||
}
|
||||
|
||||
void lifo_peek(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(data, ptr->data + ((ptr->len - 1) * ptr->data_len), ptr->data_len);
|
||||
}
|
33
ESP32QRCodeReader_Page/collections.h
Normal file
33
ESP32QRCodeReader_Page/collections.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2017 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef __COLLECTIONS_H__
|
||||
#define __COLLECTIONS_H__
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
//////////
|
||||
// lifo //
|
||||
//////////
|
||||
|
||||
typedef struct lifo
|
||||
{
|
||||
size_t len, size, data_len;
|
||||
char *data;
|
||||
}
|
||||
__attribute__((aligned(8))) lifo_t;
|
||||
|
||||
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len);
|
||||
void lifo_alloc_all(lifo_t *ptr, size_t *size, size_t data_len);
|
||||
void lifo_free(lifo_t *ptr);
|
||||
void lifo_clear(lifo_t *ptr);
|
||||
size_t lifo_size(lifo_t *ptr);
|
||||
bool lifo_is_not_empty(lifo_t *ptr);
|
||||
bool lifo_is_not_full(lifo_t *ptr);
|
||||
void lifo_enqueue(lifo_t *ptr, void *data);
|
||||
void lifo_dequeue(lifo_t *ptr, void *data);
|
||||
void lifo_poke(lifo_t *ptr, void *data);
|
||||
void lifo_peek(lifo_t *ptr, void *data);
|
||||
|
||||
#endif /* __COLLECTIONS_H__ */
|
983
ESP32QRCodeReader_Page/decode.c
Normal file
983
ESP32QRCodeReader_Page/decode.c
Normal file
@ -0,0 +1,983 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "quirc_internal.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_POLY 64
|
||||
|
||||
/************************************************************************
|
||||
* Galois fields
|
||||
*/
|
||||
|
||||
struct galois_field
|
||||
{
|
||||
int p;
|
||||
const uint8_t *log;
|
||||
const uint8_t *exp;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
static const uint8_t gf16_exp[16] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x03, 0x06, 0x0c, 0x0b,
|
||||
0x05, 0x0a, 0x07, 0x0e, 0x0f, 0x0d, 0x09, 0x01};
|
||||
|
||||
static const uint8_t gf16_log[16] = {
|
||||
0x00, 0x0f, 0x01, 0x04, 0x02, 0x08, 0x05, 0x0a,
|
||||
0x03, 0x0e, 0x09, 0x07, 0x06, 0x0d, 0x0b, 0x0c};
|
||||
|
||||
static const struct galois_field gf16 = {
|
||||
.p = 15,
|
||||
.log = gf16_log,
|
||||
.exp = gf16_exp};
|
||||
|
||||
static const uint8_t gf256_exp[256] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
|
||||
0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
|
||||
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
|
||||
0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
|
||||
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
|
||||
0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
|
||||
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
|
||||
0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
|
||||
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
|
||||
0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
|
||||
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
|
||||
0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
|
||||
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
|
||||
0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
|
||||
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
|
||||
0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
|
||||
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
|
||||
0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
|
||||
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
|
||||
0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
|
||||
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
|
||||
0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
|
||||
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
|
||||
0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
|
||||
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
|
||||
0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
|
||||
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
|
||||
0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
|
||||
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
|
||||
0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
|
||||
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
|
||||
0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01};
|
||||
|
||||
static const uint8_t gf256_log[256] = {
|
||||
0x00, 0xff, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
|
||||
0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
|
||||
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
|
||||
0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
|
||||
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
|
||||
0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
|
||||
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
|
||||
0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
|
||||
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
|
||||
0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
|
||||
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
|
||||
0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
|
||||
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
|
||||
0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
|
||||
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
|
||||
0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
|
||||
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
|
||||
0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
|
||||
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
|
||||
0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
|
||||
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
|
||||
0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
|
||||
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
|
||||
0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
|
||||
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
|
||||
0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
|
||||
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
|
||||
0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
|
||||
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
|
||||
0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
|
||||
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
|
||||
0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf};
|
||||
|
||||
const static struct galois_field gf256 = {
|
||||
.p = 255,
|
||||
.log = gf256_log,
|
||||
.exp = gf256_exp};
|
||||
|
||||
/************************************************************************
|
||||
* Polynomial operations
|
||||
*/
|
||||
|
||||
static void poly_add(uint8_t *dst, const uint8_t *src, uint8_t c,
|
||||
int shift, const struct galois_field *gf)
|
||||
{
|
||||
int i;
|
||||
int log_c = gf->log[c];
|
||||
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_POLY; i++)
|
||||
{
|
||||
int p = i + shift;
|
||||
uint8_t v = src[i];
|
||||
|
||||
if (p < 0 || p >= MAX_POLY)
|
||||
continue;
|
||||
if (!v)
|
||||
continue;
|
||||
|
||||
dst[p] ^= gf->exp[(gf->log[v] + log_c) % gf->p];
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t poly_eval(const uint8_t *s, uint8_t x,
|
||||
const struct galois_field *gf)
|
||||
{
|
||||
int i;
|
||||
uint8_t sum = 0;
|
||||
uint8_t log_x = gf->log[x];
|
||||
|
||||
if (!x)
|
||||
return s[0];
|
||||
|
||||
for (i = 0; i < MAX_POLY; i++)
|
||||
{
|
||||
uint8_t c = s[i];
|
||||
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
sum ^= gf->exp[(gf->log[c] + log_x * i) % gf->p];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Berlekamp-Massey algorithm for finding error locator polynomials.
|
||||
*/
|
||||
|
||||
static void berlekamp_massey(const uint8_t *s, int N,
|
||||
const struct galois_field *gf,
|
||||
uint8_t *sigma)
|
||||
{
|
||||
uint8_t C[MAX_POLY];
|
||||
uint8_t B[MAX_POLY];
|
||||
int L = 0;
|
||||
int m = 1;
|
||||
uint8_t b = 1;
|
||||
int n;
|
||||
|
||||
memset(B, 0, sizeof(B));
|
||||
memset(C, 0, sizeof(C));
|
||||
B[0] = 1;
|
||||
C[0] = 1;
|
||||
|
||||
for (n = 0; n < N; n++)
|
||||
{
|
||||
uint8_t d = s[n];
|
||||
uint8_t mult;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= L; i++)
|
||||
{
|
||||
if (!(C[i] && s[n - i]))
|
||||
continue;
|
||||
|
||||
d ^= gf->exp[(gf->log[C[i]] +
|
||||
gf->log[s[n - i]]) %
|
||||
gf->p];
|
||||
}
|
||||
|
||||
mult = gf->exp[(gf->p - gf->log[b] + gf->log[d]) % gf->p];
|
||||
|
||||
if (!d)
|
||||
{
|
||||
m++;
|
||||
}
|
||||
else if (L * 2 <= n)
|
||||
{
|
||||
uint8_t T[MAX_POLY];
|
||||
|
||||
memcpy(T, C, sizeof(T));
|
||||
poly_add(C, B, mult, m, gf);
|
||||
memcpy(B, T, sizeof(B));
|
||||
L = n + 1 - L;
|
||||
b = d;
|
||||
m = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
poly_add(C, B, mult, m, gf);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(sigma, C, MAX_POLY);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Code stream error correction
|
||||
*
|
||||
* Generator polynomial for GF(2^8) is x^8 + x^4 + x^3 + x^2 + 1
|
||||
*/
|
||||
|
||||
static int block_syndromes(const uint8_t *data, int bs, int npar, uint8_t *s)
|
||||
{
|
||||
int nonzero = 0;
|
||||
int i;
|
||||
|
||||
memset(s, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < npar; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < bs; j++)
|
||||
{
|
||||
uint8_t c = data[bs - j - 1];
|
||||
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
s[i] ^= gf256_exp[((int)gf256_log[c] +
|
||||
i * j) %
|
||||
255];
|
||||
}
|
||||
|
||||
if (s[i])
|
||||
nonzero = 1;
|
||||
}
|
||||
|
||||
return nonzero;
|
||||
}
|
||||
|
||||
static void eloc_poly(uint8_t *omega,
|
||||
const uint8_t *s, const uint8_t *sigma,
|
||||
int npar)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(omega, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < npar; i++)
|
||||
{
|
||||
const uint8_t a = sigma[i];
|
||||
const uint8_t log_a = gf256_log[a];
|
||||
int j;
|
||||
|
||||
if (!a)
|
||||
continue;
|
||||
|
||||
for (j = 0; j + 1 < MAX_POLY; j++)
|
||||
{
|
||||
const uint8_t b = s[j + 1];
|
||||
|
||||
if (i + j >= npar)
|
||||
break;
|
||||
|
||||
if (!b)
|
||||
continue;
|
||||
|
||||
omega[i + j] ^=
|
||||
gf256_exp[(log_a + gf256_log[b]) % 255];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static quirc_decode_error_t correct_block(uint8_t *data,
|
||||
const struct quirc_rs_params *ecc)
|
||||
{
|
||||
int npar = ecc->bs - ecc->dw;
|
||||
uint8_t s[MAX_POLY];
|
||||
uint8_t sigma[MAX_POLY];
|
||||
uint8_t sigma_deriv[MAX_POLY];
|
||||
uint8_t omega[MAX_POLY];
|
||||
int i;
|
||||
|
||||
/* Compute syndrome vector */
|
||||
if (!block_syndromes(data, ecc->bs, npar, s))
|
||||
return QUIRC_SUCCESS;
|
||||
|
||||
berlekamp_massey(s, npar, &gf256, sigma);
|
||||
|
||||
/* Compute derivative of sigma */
|
||||
memset(sigma_deriv, 0, MAX_POLY);
|
||||
for (i = 0; i + 1 < MAX_POLY; i += 2)
|
||||
sigma_deriv[i] = sigma[i + 1];
|
||||
|
||||
/* Compute error evaluator polynomial */
|
||||
eloc_poly(omega, s, sigma, npar - 1);
|
||||
|
||||
/* Find error locations and magnitudes */
|
||||
for (i = 0; i < ecc->bs; i++)
|
||||
{
|
||||
uint8_t xinv = gf256_exp[255 - i];
|
||||
|
||||
if (!poly_eval(sigma, xinv, &gf256))
|
||||
{
|
||||
uint8_t sd_x = poly_eval(sigma_deriv, xinv, &gf256);
|
||||
uint8_t omega_x = poly_eval(omega, xinv, &gf256);
|
||||
uint8_t error = gf256_exp[(255 - gf256_log[sd_x] +
|
||||
gf256_log[omega_x]) %
|
||||
255];
|
||||
|
||||
data[ecc->bs - i - 1] ^= error;
|
||||
}
|
||||
}
|
||||
|
||||
if (block_syndromes(data, ecc->bs, npar, s))
|
||||
return QUIRC_ERROR_DATA_ECC;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Format value error correction
|
||||
*
|
||||
* Generator polynomial for GF(2^4) is x^4 + x + 1
|
||||
*/
|
||||
|
||||
#define FORMAT_MAX_ERROR 3
|
||||
#define FORMAT_SYNDROMES (FORMAT_MAX_ERROR * 2)
|
||||
#define FORMAT_BITS 15
|
||||
|
||||
static int format_syndromes(uint16_t u, uint8_t *s)
|
||||
{
|
||||
int i;
|
||||
int nonzero = 0;
|
||||
|
||||
memset(s, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < FORMAT_SYNDROMES; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
s[i] = 0;
|
||||
for (j = 0; j < FORMAT_BITS; j++)
|
||||
if (u & (1 << j))
|
||||
s[i] ^= gf16_exp[((i + 1) * j) % 15];
|
||||
|
||||
if (s[i])
|
||||
nonzero = 1;
|
||||
}
|
||||
|
||||
return nonzero;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t correct_format(uint16_t *f_ret)
|
||||
{
|
||||
uint16_t u = *f_ret;
|
||||
int i;
|
||||
uint8_t s[MAX_POLY];
|
||||
uint8_t sigma[MAX_POLY];
|
||||
|
||||
/* Evaluate U (received codeword) at each of alpha_1 .. alpha_6
|
||||
* to get S_1 .. S_6 (but we index them from 0).
|
||||
*/
|
||||
if (!format_syndromes(u, s))
|
||||
return QUIRC_SUCCESS;
|
||||
|
||||
berlekamp_massey(s, FORMAT_SYNDROMES, &gf16, sigma);
|
||||
|
||||
/* Now, find the roots of the polynomial */
|
||||
for (i = 0; i < 15; i++)
|
||||
if (!poly_eval(sigma, gf16_exp[15 - i], &gf16))
|
||||
u ^= (1 << i);
|
||||
|
||||
if (format_syndromes(u, s))
|
||||
return QUIRC_ERROR_FORMAT_ECC;
|
||||
|
||||
*f_ret = u;
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Decoder algorithm
|
||||
*/
|
||||
|
||||
struct datastream
|
||||
{
|
||||
uint8_t raw[QUIRC_MAX_PAYLOAD];
|
||||
int data_bits;
|
||||
int ptr;
|
||||
|
||||
uint8_t data[QUIRC_MAX_PAYLOAD];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
static inline int grid_bit(const struct quirc_code *code, int x, int y)
|
||||
{
|
||||
int p = y * code->size + x;
|
||||
|
||||
return (code->cell_bitmap[p >> 3] >> (p & 7)) & 1;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t read_format(const struct quirc_code *code,
|
||||
struct quirc_data *data, int which)
|
||||
{
|
||||
int i;
|
||||
uint16_t format = 0;
|
||||
uint16_t fdata;
|
||||
quirc_decode_error_t err;
|
||||
|
||||
if (which)
|
||||
{
|
||||
for (i = 0; i < 7; i++)
|
||||
format = (format << 1) |
|
||||
grid_bit(code, 8, code->size - 1 - i);
|
||||
for (i = 0; i < 8; i++)
|
||||
format = (format << 1) |
|
||||
grid_bit(code, code->size - 8 + i, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const int xs[15] = {
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 4, 3, 2, 1, 0};
|
||||
static const int ys[15] = {
|
||||
0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 8, 8, 8, 8, 8};
|
||||
|
||||
for (i = 14; i >= 0; i--)
|
||||
format = (format << 1) | grid_bit(code, xs[i], ys[i]);
|
||||
}
|
||||
|
||||
format ^= 0x5412;
|
||||
|
||||
err = correct_format(&format);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
fdata = format >> 10;
|
||||
data->ecc_level = fdata >> 3;
|
||||
data->mask = fdata & 7;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static int mask_bit(int mask, int i, int j)
|
||||
{
|
||||
switch (mask)
|
||||
{
|
||||
case 0:
|
||||
return !((i + j) % 2);
|
||||
case 1:
|
||||
return !(i % 2);
|
||||
case 2:
|
||||
return !(j % 3);
|
||||
case 3:
|
||||
return !((i + j) % 3);
|
||||
case 4:
|
||||
return !(((i / 2) + (j / 3)) % 2);
|
||||
case 5:
|
||||
return !((i * j) % 2 + (i * j) % 3);
|
||||
case 6:
|
||||
return !(((i * j) % 2 + (i * j) % 3) % 2);
|
||||
case 7:
|
||||
return !(((i * j) % 3 + (i + j) % 2) % 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reserved_cell(int version, int i, int j)
|
||||
{
|
||||
const struct quirc_version_info *ver = &quirc_version_db[version];
|
||||
int size = version * 4 + 17;
|
||||
int ai = -1, aj = -1, a;
|
||||
|
||||
/* Finder + format: top left */
|
||||
if (i < 9 && j < 9)
|
||||
return 1;
|
||||
|
||||
/* Finder + format: bottom left */
|
||||
if (i + 8 >= size && j < 9)
|
||||
return 1;
|
||||
|
||||
/* Finder + format: top right */
|
||||
if (i < 9 && j + 8 >= size)
|
||||
return 1;
|
||||
|
||||
/* Exclude timing patterns */
|
||||
if (i == 6 || j == 6)
|
||||
return 1;
|
||||
|
||||
/* Exclude version info, if it exists. Version info sits adjacent to
|
||||
* the top-right and bottom-left finders in three rows, bounded by
|
||||
* the timing pattern.
|
||||
*/
|
||||
if (version >= 7)
|
||||
{
|
||||
if (i < 6 && j + 11 >= size)
|
||||
return 1;
|
||||
if (i + 11 >= size && j < 6)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Exclude alignment patterns */
|
||||
for (a = 0; a < QUIRC_MAX_ALIGNMENT && ver->apat[a]; a++)
|
||||
{
|
||||
int p = ver->apat[a];
|
||||
|
||||
if (abs(p - i) < 3)
|
||||
ai = a;
|
||||
if (abs(p - j) < 3)
|
||||
aj = a;
|
||||
}
|
||||
|
||||
if (ai >= 0 && aj >= 0)
|
||||
{
|
||||
a--;
|
||||
if (ai > 0 && ai < a)
|
||||
return 1;
|
||||
if (aj > 0 && aj < a)
|
||||
return 1;
|
||||
if (aj == a && ai == a)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void read_bit(const struct quirc_code *code,
|
||||
struct quirc_data *data,
|
||||
struct datastream *ds, int i, int j)
|
||||
{
|
||||
int bitpos = ds->data_bits & 7;
|
||||
int bytepos = ds->data_bits >> 3;
|
||||
int v = grid_bit(code, j, i);
|
||||
|
||||
if (mask_bit(data->mask, i, j))
|
||||
v ^= 1;
|
||||
|
||||
if (v)
|
||||
ds->raw[bytepos] |= (0x80 >> bitpos);
|
||||
|
||||
ds->data_bits++;
|
||||
}
|
||||
|
||||
static void read_data(const struct quirc_code *code,
|
||||
struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int y = code->size - 1;
|
||||
int x = code->size - 1;
|
||||
int dir = -1;
|
||||
|
||||
while (x > 0)
|
||||
{
|
||||
if (x == 6)
|
||||
x--;
|
||||
|
||||
if (!reserved_cell(data->version, y, x))
|
||||
read_bit(code, data, ds, y, x);
|
||||
|
||||
if (!reserved_cell(data->version, y, x - 1))
|
||||
read_bit(code, data, ds, y, x - 1);
|
||||
|
||||
y += dir;
|
||||
if (y < 0 || y >= code->size)
|
||||
{
|
||||
dir = -dir;
|
||||
x -= 2;
|
||||
y += dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static quirc_decode_error_t codestream_ecc(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
const struct quirc_version_info *ver =
|
||||
&quirc_version_db[data->version];
|
||||
const struct quirc_rs_params *sb_ecc = &ver->ecc[data->ecc_level];
|
||||
struct quirc_rs_params lb_ecc;
|
||||
const int lb_count =
|
||||
(ver->data_bytes - sb_ecc->bs * sb_ecc->ns) / (sb_ecc->bs + 1);
|
||||
const int bc = lb_count + sb_ecc->ns;
|
||||
const int ecc_offset = sb_ecc->dw * bc + lb_count;
|
||||
int dst_offset = 0;
|
||||
int i;
|
||||
|
||||
memcpy(&lb_ecc, sb_ecc, sizeof(lb_ecc));
|
||||
lb_ecc.dw++;
|
||||
lb_ecc.bs++;
|
||||
|
||||
for (i = 0; i < bc; i++)
|
||||
{
|
||||
uint8_t *dst = ds->data + dst_offset;
|
||||
const struct quirc_rs_params *ecc =
|
||||
(i < sb_ecc->ns) ? sb_ecc : &lb_ecc;
|
||||
const int num_ec = ecc->bs - ecc->dw;
|
||||
quirc_decode_error_t err;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < ecc->dw; j++)
|
||||
dst[j] = ds->raw[j * bc + i];
|
||||
for (j = 0; j < num_ec; j++)
|
||||
dst[ecc->dw + j] = ds->raw[ecc_offset + j * bc + i];
|
||||
|
||||
err = correct_block(dst, ecc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dst_offset += ecc->dw;
|
||||
}
|
||||
|
||||
ds->data_bits = dst_offset * 8;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int bits_remaining(const struct datastream *ds)
|
||||
{
|
||||
return ds->data_bits - ds->ptr;
|
||||
}
|
||||
|
||||
static int take_bits(struct datastream *ds, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (len && (ds->ptr < ds->data_bits))
|
||||
{
|
||||
uint8_t b = ds->data[ds->ptr >> 3];
|
||||
int bitpos = ds->ptr & 7;
|
||||
|
||||
ret <<= 1;
|
||||
if ((b << bitpos) & 0x80)
|
||||
ret |= 1;
|
||||
|
||||
ds->ptr++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int numeric_tuple(struct quirc_data *data,
|
||||
struct datastream *ds,
|
||||
int bits, int digits)
|
||||
{
|
||||
int tuple;
|
||||
int i;
|
||||
|
||||
if (bits_remaining(ds) < bits)
|
||||
return -1;
|
||||
|
||||
tuple = take_bits(ds, bits);
|
||||
|
||||
for (i = digits - 1; i >= 0; i--)
|
||||
{
|
||||
data->payload[data->payload_len + i] = tuple % 10 + '0';
|
||||
tuple /= 10;
|
||||
}
|
||||
|
||||
data->payload_len += digits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_numeric(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 14;
|
||||
int count;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 10;
|
||||
else if (data->version < 27)
|
||||
bits = 12;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
|
||||
while (count >= 3)
|
||||
{
|
||||
if (numeric_tuple(data, ds, 10, 3) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 3;
|
||||
}
|
||||
|
||||
if (count >= 2)
|
||||
{
|
||||
if (numeric_tuple(data, ds, 7, 2) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
if (numeric_tuple(data, ds, 4, 1) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count--;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static int alpha_tuple(struct quirc_data *data,
|
||||
struct datastream *ds,
|
||||
int bits, int digits)
|
||||
{
|
||||
int tuple;
|
||||
int i;
|
||||
|
||||
if (bits_remaining(ds) < bits)
|
||||
return -1;
|
||||
|
||||
tuple = take_bits(ds, bits);
|
||||
|
||||
for (i = 0; i < digits; i++)
|
||||
{
|
||||
static const char *alpha_map =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
|
||||
|
||||
data->payload[data->payload_len + digits - i - 1] =
|
||||
alpha_map[tuple % 45];
|
||||
tuple /= 45;
|
||||
}
|
||||
|
||||
data->payload_len += digits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_alpha(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 13;
|
||||
int count;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 9;
|
||||
else if (data->version < 27)
|
||||
bits = 11;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
|
||||
while (count >= 2)
|
||||
{
|
||||
if (alpha_tuple(data, ds, 11, 2) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
if (alpha_tuple(data, ds, 6, 1) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count--;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_byte(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 16;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 8;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
if (bits_remaining(ds) < count * 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
data->payload[data->payload_len++] = take_bits(ds, 8);
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_kanji(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 12;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 8;
|
||||
else if (data->version < 27)
|
||||
bits = 10;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count * 2 + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
if (bits_remaining(ds) < count * 13)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
int d = take_bits(ds, 13);
|
||||
int msB = d / 0xc0;
|
||||
int lsB = d % 0xc0;
|
||||
int intermediate = (msB << 8) | lsB;
|
||||
uint16_t sjw;
|
||||
|
||||
if (intermediate + 0x8140 <= 0x9ffc)
|
||||
{
|
||||
/* bytes are in the range 0x8140 to 0x9FFC */
|
||||
sjw = intermediate + 0x8140;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bytes are in the range 0xE040 to 0xEBBF */
|
||||
sjw = intermediate + 0xc140;
|
||||
}
|
||||
|
||||
data->payload[data->payload_len++] = sjw >> 8;
|
||||
data->payload[data->payload_len++] = sjw & 0xff;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_eci(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
if (bits_remaining(ds) < 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = take_bits(ds, 8);
|
||||
|
||||
if ((data->eci & 0xc0) == 0x80)
|
||||
{
|
||||
if (bits_remaining(ds) < 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = (data->eci << 8) | take_bits(ds, 8);
|
||||
}
|
||||
else if ((data->eci & 0xe0) == 0xc0)
|
||||
{
|
||||
if (bits_remaining(ds) < 16)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = (data->eci << 16) | take_bits(ds, 16);
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_payload(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
while (bits_remaining(ds) >= 4)
|
||||
{
|
||||
quirc_decode_error_t err = QUIRC_SUCCESS;
|
||||
int type = take_bits(ds, 4);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case QUIRC_DATA_TYPE_NUMERIC:
|
||||
err = decode_numeric(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_ALPHA:
|
||||
err = decode_alpha(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_BYTE:
|
||||
err = decode_byte(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_KANJI:
|
||||
err = decode_kanji(data, ds);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
err = decode_eci(data, ds);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!(type & (type - 1)) && (type > data->data_type))
|
||||
data->data_type = type;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
/* Add nul terminator to all payloads */
|
||||
if (data->payload_len >= sizeof(data->payload))
|
||||
data->payload_len--;
|
||||
data->payload[data->payload_len] = 0;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
||||
struct quirc_data *data)
|
||||
{
|
||||
quirc_decode_error_t err;
|
||||
struct datastream *ds = ps_malloc(sizeof(struct datastream));
|
||||
|
||||
if ((code->size - 17) % 4)
|
||||
{
|
||||
free(ds);
|
||||
return QUIRC_ERROR_INVALID_GRID_SIZE;
|
||||
}
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
memset(ds, 0, sizeof(*ds));
|
||||
|
||||
data->version = (code->size - 17) / 4;
|
||||
|
||||
if (data->version < 1 ||
|
||||
data->version > QUIRC_MAX_VERSION)
|
||||
{
|
||||
free(ds);
|
||||
return QUIRC_ERROR_INVALID_VERSION;
|
||||
}
|
||||
|
||||
/* Read format information -- try both locations */
|
||||
err = read_format(code, data, 0);
|
||||
if (err)
|
||||
err = read_format(code, data, 1);
|
||||
if (err)
|
||||
{
|
||||
free(ds);
|
||||
return err;
|
||||
}
|
||||
|
||||
read_data(code, data, ds);
|
||||
err = codestream_ecc(data, ds);
|
||||
if (err)
|
||||
{
|
||||
free(ds);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = decode_payload(data, ds);
|
||||
if (err)
|
||||
{
|
||||
free(ds);
|
||||
return err;
|
||||
}
|
||||
|
||||
free(ds);
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
70
ESP32QRCodeReader_Page/fmath.h
Normal file
70
ESP32QRCodeReader_Page/fmath.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Fast approximate math functions.
|
||||
*
|
||||
*/
|
||||
#ifndef __FMATH_H
|
||||
#define __FMATH_H
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
static inline float fast_sqrtf(float x)
|
||||
{
|
||||
//return sqrtf(x);
|
||||
asm("fsqrt.s %0, %1"
|
||||
: "=f"(x)
|
||||
: "f"(x));
|
||||
return x;
|
||||
}
|
||||
static inline int fast_floorf(float x)
|
||||
{
|
||||
return (int)(x);
|
||||
}
|
||||
|
||||
static inline int fast_ceilf(float x)
|
||||
{
|
||||
return (int)(x + 0.9999f);
|
||||
}
|
||||
|
||||
static inline int fast_roundf(float x)
|
||||
{
|
||||
return (int)(x);
|
||||
}
|
||||
|
||||
static inline float fast_fabsf(float d)
|
||||
{
|
||||
return fabsf(d);
|
||||
}
|
||||
|
||||
extern int fast_floorf(float x);
|
||||
extern int fast_ceilf(float x);
|
||||
extern int fast_roundf(float x);
|
||||
extern float fast_atanf(float x);
|
||||
extern float fast_atan2f(float y, float x);
|
||||
extern float fast_expf(float x);
|
||||
extern float fast_cbrtf(float d);
|
||||
extern float fast_fabsf(float d);
|
||||
extern float fast_log(float x);
|
||||
extern float fast_log2(float x);
|
||||
extern float fast_powf(float a, float b);
|
||||
|
||||
/*#define fast_sqrtf(x) (sqrtf(x))
|
||||
#define fast_floorf(x) ((int)floorf(x))
|
||||
#define fast_ceilf(x) ((int)ceilf(x))
|
||||
#define fast_roundf(x) ((int)roundf(x))
|
||||
#define fast_atanf(x) (atanf(x))
|
||||
#define fast_atan2f(x,y) (atan2f((x),(y)))
|
||||
#define fast_expf(x) (expf(x))
|
||||
#define fast_cbrtf(x) (cbrtf(x))
|
||||
#define fast_fabsf(x) (fabsf(x))
|
||||
#define fast_log(x) (log(x))
|
||||
#define fast_log2(x) (log2(x))
|
||||
#define fast_powf(x,y) (powf((x),(y)))
|
||||
*/
|
||||
|
||||
extern const float cos_table[360];
|
||||
extern const float sin_table[360];
|
||||
#endif // __FMATH_H
|
1286
ESP32QRCodeReader_Page/identify.c
Normal file
1286
ESP32QRCodeReader_Page/identify.c
Normal file
File diff suppressed because it is too large
Load Diff
104
ESP32QRCodeReader_Page/quirc.c
Normal file
104
ESP32QRCodeReader_Page/quirc.c
Normal file
@ -0,0 +1,104 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "quirc_internal.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
const char *quirc_version(void)
|
||||
{
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
//static struct quirc _q;
|
||||
struct quirc *quirc_new(void)
|
||||
{
|
||||
struct quirc *q = ps_malloc(sizeof(*q));
|
||||
|
||||
if (!q)
|
||||
return NULL;
|
||||
|
||||
memset(q, 0, sizeof(*q));
|
||||
return q;
|
||||
}
|
||||
|
||||
void quirc_destroy(struct quirc *q)
|
||||
{
|
||||
if (q->image)
|
||||
if (q->image)
|
||||
free(q->image);
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
if (q->pixels)
|
||||
free(q->pixels);
|
||||
|
||||
if (q)
|
||||
free(q);
|
||||
}
|
||||
|
||||
//static quirc_pixel_t img_buf[320*240];
|
||||
int quirc_resize(struct quirc *q, int w, int h)
|
||||
{
|
||||
if (q->image)
|
||||
{
|
||||
free(q->image);
|
||||
}
|
||||
uint8_t *new_image = ps_malloc(w * h);
|
||||
|
||||
if (!new_image)
|
||||
return -1;
|
||||
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
{ //should gray, 1==1
|
||||
size_t new_size = w * h * sizeof(quirc_pixel_t);
|
||||
if (q->pixels)
|
||||
free(q->pixels);
|
||||
quirc_pixel_t *new_pixels = ps_malloc(new_size);
|
||||
if (!new_pixels)
|
||||
{
|
||||
free(new_image);
|
||||
return -1;
|
||||
}
|
||||
q->pixels = new_pixels;
|
||||
}
|
||||
q->image = new_image;
|
||||
q->w = w;
|
||||
q->h = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int quirc_count(const struct quirc *q)
|
||||
{
|
||||
return q->num_grids;
|
||||
}
|
||||
|
||||
static const char *const error_table[] = {
|
||||
[QUIRC_SUCCESS] = "Success",
|
||||
[QUIRC_ERROR_INVALID_GRID_SIZE] = "Invalid grid size",
|
||||
[QUIRC_ERROR_INVALID_VERSION] = "Invalid version",
|
||||
[QUIRC_ERROR_FORMAT_ECC] = "Format data ECC failure",
|
||||
[QUIRC_ERROR_DATA_ECC] = "ECC failure",
|
||||
[QUIRC_ERROR_UNKNOWN_DATA_TYPE] = "Unknown data type",
|
||||
[QUIRC_ERROR_DATA_OVERFLOW] = "Data overflow",
|
||||
[QUIRC_ERROR_DATA_UNDERFLOW] = "Data underflow"};
|
||||
|
||||
const char *quirc_strerror(quirc_decode_error_t err)
|
||||
{
|
||||
if (err >= 0 && err < sizeof(error_table) / sizeof(error_table[0]))
|
||||
return error_table[err];
|
||||
|
||||
return "Unknown error";
|
||||
}
|
178
ESP32QRCodeReader_Page/quirc.h
Normal file
178
ESP32QRCodeReader_Page/quirc.h
Normal file
@ -0,0 +1,178 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef QUIRC_H_
|
||||
#define QUIRC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct quirc;
|
||||
|
||||
/* Obtain the library version string. */
|
||||
const char *quirc_version(void);
|
||||
|
||||
/* Construct a new QR-code recognizer. This function will return NULL
|
||||
* if sufficient memory could not be allocated.
|
||||
*/
|
||||
struct quirc *quirc_new(void);
|
||||
|
||||
/* Destroy a QR-code recognizer. */
|
||||
void quirc_destroy(struct quirc *q);
|
||||
|
||||
/* Resize the QR-code recognizer. The size of an image must be
|
||||
* specified before codes can be analyzed.
|
||||
*
|
||||
* This function returns 0 on success, or -1 if sufficient memory could
|
||||
* not be allocated.
|
||||
*/
|
||||
int quirc_resize(struct quirc *q, int w, int h);
|
||||
|
||||
/* These functions are used to process images for QR-code recognition.
|
||||
* quirc_begin() must first be called to obtain access to a buffer into
|
||||
* which the input image should be placed. Optionally, the current
|
||||
* width and height may be returned.
|
||||
*
|
||||
* After filling the buffer, quirc_end() should be called to process
|
||||
* the image for QR-code recognition. The locations and content of each
|
||||
* code may be obtained using accessor functions described below.
|
||||
*/
|
||||
uint8_t *quirc_begin(struct quirc *q, int *w, int *h);
|
||||
void quirc_end(struct quirc *q);
|
||||
|
||||
/* This structure describes a location in the input image buffer. */
|
||||
struct quirc_point
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* This enum describes the various decoder errors which may occur. */
|
||||
typedef enum
|
||||
{
|
||||
QUIRC_SUCCESS = 0,
|
||||
QUIRC_ERROR_INVALID_GRID_SIZE,
|
||||
QUIRC_ERROR_INVALID_VERSION,
|
||||
QUIRC_ERROR_FORMAT_ECC,
|
||||
QUIRC_ERROR_DATA_ECC,
|
||||
QUIRC_ERROR_UNKNOWN_DATA_TYPE,
|
||||
QUIRC_ERROR_DATA_OVERFLOW,
|
||||
QUIRC_ERROR_DATA_UNDERFLOW
|
||||
} quirc_decode_error_t;
|
||||
|
||||
/* Return a string error message for an error code. */
|
||||
const char *quirc_strerror(quirc_decode_error_t err);
|
||||
|
||||
/* Limits on the maximum size of QR-codes and their content. */
|
||||
#define QUIRC_MAX_BITMAP 3917
|
||||
#define QUIRC_MAX_PAYLOAD 8896
|
||||
|
||||
/* QR-code ECC types. */
|
||||
#define QUIRC_ECC_LEVEL_M 0
|
||||
#define QUIRC_ECC_LEVEL_L 1
|
||||
#define QUIRC_ECC_LEVEL_H 2
|
||||
#define QUIRC_ECC_LEVEL_Q 3
|
||||
|
||||
/* QR-code data types. */
|
||||
#define QUIRC_DATA_TYPE_NUMERIC 1
|
||||
#define QUIRC_DATA_TYPE_ALPHA 2
|
||||
#define QUIRC_DATA_TYPE_BYTE 4
|
||||
#define QUIRC_DATA_TYPE_KANJI 8
|
||||
|
||||
/* Common character encodings */
|
||||
#define QUIRC_ECI_ISO_8859_1 1
|
||||
#define QUIRC_ECI_IBM437 2
|
||||
#define QUIRC_ECI_ISO_8859_2 4
|
||||
#define QUIRC_ECI_ISO_8859_3 5
|
||||
#define QUIRC_ECI_ISO_8859_4 6
|
||||
#define QUIRC_ECI_ISO_8859_5 7
|
||||
#define QUIRC_ECI_ISO_8859_6 8
|
||||
#define QUIRC_ECI_ISO_8859_7 9
|
||||
#define QUIRC_ECI_ISO_8859_8 10
|
||||
#define QUIRC_ECI_ISO_8859_9 11
|
||||
#define QUIRC_ECI_WINDOWS_874 13
|
||||
#define QUIRC_ECI_ISO_8859_13 15
|
||||
#define QUIRC_ECI_ISO_8859_15 17
|
||||
#define QUIRC_ECI_SHIFT_JIS 20
|
||||
#define QUIRC_ECI_UTF_8 26
|
||||
|
||||
/* This structure is used to return information about detected QR codes
|
||||
* in the input image.
|
||||
*/
|
||||
struct quirc_code
|
||||
{
|
||||
/* The four corners of the QR-code, from top left, clockwise */
|
||||
struct quirc_point corners[4];
|
||||
|
||||
/* The number of cells across in the QR-code. The cell bitmap
|
||||
* is a bitmask giving the actual values of cells. If the cell
|
||||
* at (x, y) is black, then the following bit is set:
|
||||
*
|
||||
* cell_bitmap[i >> 3] & (1 << (i & 7))
|
||||
*
|
||||
* where i = (y * size) + x.
|
||||
*/
|
||||
int size;
|
||||
uint8_t cell_bitmap[QUIRC_MAX_BITMAP];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* This structure holds the decoded QR-code data */
|
||||
struct quirc_data
|
||||
{
|
||||
/* Various parameters of the QR-code. These can mostly be
|
||||
* ignored if you only care about the data.
|
||||
*/
|
||||
int version;
|
||||
int ecc_level;
|
||||
int mask;
|
||||
|
||||
/* This field is the highest-valued data type found in the QR
|
||||
* code.
|
||||
*/
|
||||
int data_type;
|
||||
|
||||
/* Data payload. For the Kanji datatype, payload is encoded as
|
||||
* Shift-JIS. For all other datatypes, payload is ASCII text.
|
||||
*/
|
||||
uint8_t payload[QUIRC_MAX_PAYLOAD];
|
||||
int payload_len;
|
||||
|
||||
/* ECI assignment number */
|
||||
uint32_t eci;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* Return the number of QR-codes identified in the last processed
|
||||
* image.
|
||||
*/
|
||||
int quirc_count(const struct quirc *q);
|
||||
|
||||
/* Extract the QR-code specified by the given index. */
|
||||
void quirc_extract(const struct quirc *q, int index,
|
||||
struct quirc_code *code);
|
||||
|
||||
/* Decode a QR-code, returning the payload data. */
|
||||
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
||||
struct quirc_data *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
121
ESP32QRCodeReader_Page/quirc_internal.h
Normal file
121
ESP32QRCodeReader_Page/quirc_internal.h
Normal file
@ -0,0 +1,121 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef QUIRC_INTERNAL_H_
|
||||
#define QUIRC_INTERNAL_H_
|
||||
|
||||
#include "quirc.h"
|
||||
|
||||
#define QUIRC_PIXEL_WHITE 0
|
||||
#define QUIRC_PIXEL_BLACK 1
|
||||
#define QUIRC_PIXEL_REGION 2
|
||||
|
||||
#ifndef QUIRC_MAX_REGIONS
|
||||
#define QUIRC_MAX_REGIONS 254
|
||||
#endif
|
||||
|
||||
#define QUIRC_MAX_CAPSTONES 32
|
||||
#define QUIRC_MAX_GRIDS 8
|
||||
|
||||
#define QUIRC_PERSPECTIVE_PARAMS 8
|
||||
|
||||
#if QUIRC_MAX_REGIONS < UINT8_MAX
|
||||
typedef uint8_t quirc_pixel_t;
|
||||
#elif QUIRC_MAX_REGIONS < UINT16_MAX
|
||||
typedef uint16_t quirc_pixel_t;
|
||||
#else
|
||||
#error "QUIRC_MAX_REGIONS > 65534 is not supported"
|
||||
#endif
|
||||
|
||||
struct quirc_region
|
||||
{
|
||||
struct quirc_point seed;
|
||||
int count;
|
||||
int capstone;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_capstone
|
||||
{
|
||||
int ring;
|
||||
int stone;
|
||||
|
||||
struct quirc_point corners[4];
|
||||
struct quirc_point center;
|
||||
float c[QUIRC_PERSPECTIVE_PARAMS];
|
||||
|
||||
int qr_grid;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_grid
|
||||
{
|
||||
/* Capstone indices */
|
||||
int caps[3];
|
||||
|
||||
/* Alignment pattern region and corner */
|
||||
int align_region;
|
||||
struct quirc_point align;
|
||||
|
||||
/* Timing pattern endpoints */
|
||||
struct quirc_point tpep[3];
|
||||
int hscan;
|
||||
int vscan;
|
||||
|
||||
/* Grid size and perspective transform */
|
||||
int grid_size;
|
||||
float c[QUIRC_PERSPECTIVE_PARAMS];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc
|
||||
{
|
||||
uint8_t *image;
|
||||
quirc_pixel_t *pixels;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
int num_regions;
|
||||
struct quirc_region regions[QUIRC_MAX_REGIONS];
|
||||
|
||||
int num_capstones;
|
||||
struct quirc_capstone capstones[QUIRC_MAX_CAPSTONES];
|
||||
|
||||
int num_grids;
|
||||
struct quirc_grid grids[QUIRC_MAX_GRIDS];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/************************************************************************
|
||||
* QR-code version information database
|
||||
*/
|
||||
|
||||
#define QUIRC_MAX_VERSION 40
|
||||
#define QUIRC_MAX_ALIGNMENT 7
|
||||
|
||||
struct quirc_rs_params
|
||||
{
|
||||
uint8_t bs; /* Small block size */
|
||||
uint8_t dw; /* Small data words */
|
||||
uint8_t ns; /* Number of small blocks */
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_version_info
|
||||
{
|
||||
uint16_t data_bytes;
|
||||
uint8_t apat[QUIRC_MAX_ALIGNMENT];
|
||||
struct quirc_rs_params ecc[4];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
extern const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1];
|
||||
|
||||
#endif
|
184
ESP32QRCodeReader_Page/version_db.c
Normal file
184
ESP32QRCodeReader_Page/version_db.c
Normal file
@ -0,0 +1,184 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "quirc_internal.h"
|
||||
|
||||
const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = {
|
||||
{0},
|
||||
{/* Version 1 */
|
||||
.data_bytes = 26,
|
||||
.apat = {0},
|
||||
.ecc = {
|
||||
{.bs = 26, .dw = 16, .ns = 1},
|
||||
{.bs = 26, .dw = 19, .ns = 1},
|
||||
{.bs = 26, .dw = 9, .ns = 1},
|
||||
{.bs = 26, .dw = 13, .ns = 1}}},
|
||||
{/* Version 2 */
|
||||
.data_bytes = 44,
|
||||
.apat = {6, 18, 0},
|
||||
.ecc = {{.bs = 44, .dw = 28, .ns = 1}, {.bs = 44, .dw = 34, .ns = 1}, {.bs = 44, .dw = 16, .ns = 1}, {.bs = 44, .dw = 22, .ns = 1}}},
|
||||
{/* Version 3 */
|
||||
.data_bytes = 70,
|
||||
.apat = {6, 22, 0},
|
||||
.ecc = {{.bs = 70, .dw = 44, .ns = 1}, {.bs = 70, .dw = 55, .ns = 1}, {.bs = 35, .dw = 13, .ns = 2}, {.bs = 35, .dw = 17, .ns = 2}}},
|
||||
{/* Version 4 */
|
||||
.data_bytes = 100,
|
||||
.apat = {6, 26, 0},
|
||||
.ecc = {{.bs = 50, .dw = 32, .ns = 2}, {.bs = 100, .dw = 80, .ns = 1}, {.bs = 25, .dw = 9, .ns = 4}, {.bs = 50, .dw = 24, .ns = 2}}},
|
||||
{/* Version 5 */
|
||||
.data_bytes = 134,
|
||||
.apat = {6, 30, 0},
|
||||
.ecc = {{.bs = 67, .dw = 43, .ns = 2}, {.bs = 134, .dw = 108, .ns = 1}, {.bs = 33, .dw = 11, .ns = 2}, {.bs = 33, .dw = 15, .ns = 2}}},
|
||||
{/* Version 6 */
|
||||
.data_bytes = 172,
|
||||
.apat = {6, 34, 0},
|
||||
.ecc = {{.bs = 43, .dw = 27, .ns = 4}, {.bs = 86, .dw = 68, .ns = 2}, {.bs = 43, .dw = 15, .ns = 4}, {.bs = 43, .dw = 19, .ns = 4}}},
|
||||
{/* Version 7 */
|
||||
.data_bytes = 196,
|
||||
.apat = {6, 22, 38, 0},
|
||||
.ecc = {{.bs = 49, .dw = 31, .ns = 4}, {.bs = 98, .dw = 78, .ns = 2}, {.bs = 39, .dw = 13, .ns = 4}, {.bs = 32, .dw = 14, .ns = 2}}},
|
||||
{/* Version 8 */
|
||||
.data_bytes = 242,
|
||||
.apat = {6, 24, 42, 0},
|
||||
.ecc = {{.bs = 60, .dw = 38, .ns = 2}, {.bs = 121, .dw = 97, .ns = 2}, {.bs = 40, .dw = 14, .ns = 4}, {.bs = 40, .dw = 18, .ns = 4}}},
|
||||
{/* Version 9 */
|
||||
.data_bytes = 292,
|
||||
.apat = {6, 26, 46, 0},
|
||||
.ecc = {{.bs = 58, .dw = 36, .ns = 3}, {.bs = 146, .dw = 116, .ns = 2}, {.bs = 36, .dw = 12, .ns = 4}, {.bs = 36, .dw = 16, .ns = 4}}},
|
||||
{/* Version 10 */
|
||||
.data_bytes = 346,
|
||||
.apat = {6, 28, 50, 0},
|
||||
.ecc = {{.bs = 69, .dw = 43, .ns = 4}, {.bs = 86, .dw = 68, .ns = 2}, {.bs = 43, .dw = 15, .ns = 6}, {.bs = 43, .dw = 19, .ns = 6}}},
|
||||
{/* Version 11 */
|
||||
.data_bytes = 404,
|
||||
.apat = {6, 30, 54, 0},
|
||||
.ecc = {{.bs = 80, .dw = 50, .ns = 1}, {.bs = 101, .dw = 81, .ns = 4}, {.bs = 36, .dw = 12, .ns = 3}, {.bs = 50, .dw = 22, .ns = 4}}},
|
||||
{/* Version 12 */
|
||||
.data_bytes = 466,
|
||||
.apat = {6, 32, 58, 0},
|
||||
.ecc = {{.bs = 58, .dw = 36, .ns = 6}, {.bs = 116, .dw = 92, .ns = 2}, {.bs = 42, .dw = 14, .ns = 7}, {.bs = 46, .dw = 20, .ns = 4}}},
|
||||
{/* Version 13 */
|
||||
.data_bytes = 532,
|
||||
.apat = {6, 34, 62, 0},
|
||||
.ecc = {{.bs = 59, .dw = 37, .ns = 8}, {.bs = 133, .dw = 107, .ns = 4}, {.bs = 33, .dw = 11, .ns = 12}, {.bs = 44, .dw = 20, .ns = 8}}},
|
||||
{/* Version 14 */
|
||||
.data_bytes = 581,
|
||||
.apat = {6, 26, 46, 66, 0},
|
||||
.ecc = {{.bs = 64, .dw = 40, .ns = 4}, {.bs = 145, .dw = 115, .ns = 3}, {.bs = 36, .dw = 12, .ns = 11}, {.bs = 36, .dw = 16, .ns = 11}}},
|
||||
{/* Version 15 */
|
||||
.data_bytes = 655,
|
||||
.apat = {6, 26, 48, 70, 0},
|
||||
.ecc = {{.bs = 65, .dw = 41, .ns = 5}, {.bs = 109, .dw = 87, .ns = 5}, {.bs = 36, .dw = 12, .ns = 11}, {.bs = 54, .dw = 24, .ns = 5}}},
|
||||
{/* Version 16 */
|
||||
.data_bytes = 733,
|
||||
.apat = {6, 26, 50, 74, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 7}, {.bs = 122, .dw = 98, .ns = 5}, {.bs = 45, .dw = 15, .ns = 3}, {.bs = 43, .dw = 19, .ns = 15}}},
|
||||
{/* Version 17 */
|
||||
.data_bytes = 815,
|
||||
.apat = {6, 30, 54, 78, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 10}, {.bs = 135, .dw = 107, .ns = 1}, {.bs = 42, .dw = 14, .ns = 2}, {.bs = 50, .dw = 22, .ns = 1}}},
|
||||
{/* Version 18 */
|
||||
.data_bytes = 901,
|
||||
.apat = {6, 30, 56, 82, 0},
|
||||
.ecc = {{.bs = 69, .dw = 43, .ns = 9}, {.bs = 150, .dw = 120, .ns = 5}, {.bs = 42, .dw = 14, .ns = 2}, {.bs = 50, .dw = 22, .ns = 17}}},
|
||||
{/* Version 19 */
|
||||
.data_bytes = 991,
|
||||
.apat = {6, 30, 58, 86, 0},
|
||||
.ecc = {{.bs = 70, .dw = 44, .ns = 3}, {.bs = 141, .dw = 113, .ns = 3}, {.bs = 39, .dw = 13, .ns = 9}, {.bs = 47, .dw = 21, .ns = 17}}},
|
||||
{/* Version 20 */
|
||||
.data_bytes = 1085,
|
||||
.apat = {6, 34, 62, 90, 0},
|
||||
.ecc = {{.bs = 67, .dw = 41, .ns = 3}, {.bs = 135, .dw = 107, .ns = 3}, {.bs = 43, .dw = 15, .ns = 15}, {.bs = 54, .dw = 24, .ns = 15}}},
|
||||
{/* Version 21 */
|
||||
.data_bytes = 1156,
|
||||
.apat = {6, 28, 50, 72, 92, 0},
|
||||
.ecc = {{.bs = 68, .dw = 42, .ns = 17}, {.bs = 144, .dw = 116, .ns = 4}, {.bs = 46, .dw = 16, .ns = 19}, {.bs = 50, .dw = 22, .ns = 17}}},
|
||||
{/* Version 22 */
|
||||
.data_bytes = 1258,
|
||||
.apat = {6, 26, 50, 74, 98, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 17}, {.bs = 139, .dw = 111, .ns = 2}, {.bs = 37, .dw = 13, .ns = 34}, {.bs = 54, .dw = 24, .ns = 7}}},
|
||||
{/* Version 23 */
|
||||
.data_bytes = 1364,
|
||||
.apat = {6, 30, 54, 78, 102, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 4}, {.bs = 151, .dw = 121, .ns = 4}, {.bs = 45, .dw = 15, .ns = 16}, {.bs = 54, .dw = 24, .ns = 11}}},
|
||||
{/* Version 24 */
|
||||
.data_bytes = 1474,
|
||||
.apat = {6, 28, 54, 80, 106, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 6}, {.bs = 147, .dw = 117, .ns = 6}, {.bs = 46, .dw = 16, .ns = 30}, {.bs = 54, .dw = 24, .ns = 11}}},
|
||||
{/* Version 25 */
|
||||
.data_bytes = 1588,
|
||||
.apat = {6, 32, 58, 84, 110, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 8}, {.bs = 132, .dw = 106, .ns = 8}, {.bs = 45, .dw = 15, .ns = 22}, {.bs = 54, .dw = 24, .ns = 7}}},
|
||||
{/* Version 26 */
|
||||
.data_bytes = 1706,
|
||||
.apat = {6, 30, 58, 86, 114, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 19}, {.bs = 142, .dw = 114, .ns = 10}, {.bs = 46, .dw = 16, .ns = 33}, {.bs = 50, .dw = 22, .ns = 28}}},
|
||||
{/* Version 27 */
|
||||
.data_bytes = 1828,
|
||||
.apat = {6, 34, 62, 90, 118, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 22}, {.bs = 152, .dw = 122, .ns = 8}, {.bs = 45, .dw = 15, .ns = 12}, {.bs = 53, .dw = 23, .ns = 8}}},
|
||||
{/* Version 28 */
|
||||
.data_bytes = 1921,
|
||||
.apat = {6, 26, 50, 74, 98, 122, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 3}, {.bs = 147, .dw = 117, .ns = 3}, {.bs = 45, .dw = 15, .ns = 11}, {.bs = 54, .dw = 24, .ns = 4}}},
|
||||
{/* Version 29 */
|
||||
.data_bytes = 2051,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 21}, {.bs = 146, .dw = 116, .ns = 7}, {.bs = 45, .dw = 15, .ns = 19}, {.bs = 53, .dw = 23, .ns = 1}}},
|
||||
{/* Version 30 */
|
||||
.data_bytes = 2185,
|
||||
.apat = {6, 26, 52, 78, 104, 130, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 19}, {.bs = 145, .dw = 115, .ns = 5}, {.bs = 45, .dw = 15, .ns = 23}, {.bs = 54, .dw = 24, .ns = 15}}},
|
||||
{/* Version 31 */
|
||||
.data_bytes = 2323,
|
||||
.apat = {6, 30, 56, 82, 108, 134, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 2}, {.bs = 145, .dw = 115, .ns = 13}, {.bs = 45, .dw = 15, .ns = 23}, {.bs = 54, .dw = 24, .ns = 42}}},
|
||||
{/* Version 32 */
|
||||
.data_bytes = 2465,
|
||||
.apat = {6, 34, 60, 86, 112, 138, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 10}, {.bs = 145, .dw = 115, .ns = 17}, {.bs = 45, .dw = 15, .ns = 19}, {.bs = 54, .dw = 24, .ns = 10}}},
|
||||
{/* Version 33 */
|
||||
.data_bytes = 2611,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 14}, {.bs = 145, .dw = 115, .ns = 17}, {.bs = 45, .dw = 15, .ns = 11}, {.bs = 54, .dw = 24, .ns = 29}}},
|
||||
{/* Version 34 */
|
||||
.data_bytes = 2761,
|
||||
.apat = {6, 34, 62, 90, 118, 146, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 14}, {.bs = 145, .dw = 115, .ns = 13}, {.bs = 46, .dw = 16, .ns = 59}, {.bs = 54, .dw = 24, .ns = 44}}},
|
||||
{/* Version 35 */
|
||||
.data_bytes = 2876,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 150},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 12}, {.bs = 151, .dw = 121, .ns = 12}, {.bs = 45, .dw = 15, .ns = 22}, {.bs = 54, .dw = 24, .ns = 39}}},
|
||||
{/* Version 36 */
|
||||
.data_bytes = 3034,
|
||||
.apat = {6, 24, 50, 76, 102, 128, 154},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 6}, {.bs = 151, .dw = 121, .ns = 6}, {.bs = 45, .dw = 15, .ns = 2}, {.bs = 54, .dw = 24, .ns = 46}}},
|
||||
{/* Version 37 */
|
||||
.data_bytes = 3196,
|
||||
.apat = {6, 28, 54, 80, 106, 132, 158},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 29}, {.bs = 152, .dw = 122, .ns = 17}, {.bs = 45, .dw = 15, .ns = 24}, {.bs = 54, .dw = 24, .ns = 49}}},
|
||||
{/* Version 38 */
|
||||
.data_bytes = 3362,
|
||||
.apat = {6, 32, 58, 84, 110, 136, 162},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 13}, {.bs = 152, .dw = 122, .ns = 4}, {.bs = 45, .dw = 15, .ns = 42}, {.bs = 54, .dw = 24, .ns = 48}}},
|
||||
{/* Version 39 */
|
||||
.data_bytes = 3532,
|
||||
.apat = {6, 26, 54, 82, 110, 138, 166},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 40}, {.bs = 147, .dw = 117, .ns = 20}, {.bs = 45, .dw = 15, .ns = 10}, {.bs = 54, .dw = 24, .ns = 43}}},
|
||||
{/* Version 40 */
|
||||
.data_bytes = 3706,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 170},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 18}, {.bs = 148, .dw = 118, .ns = 19}, {.bs = 45, .dw = 15, .ns = 20}, {.bs = 54, .dw = 24, .ns = 34}}}};
|
24
ESP32QRReaderDBWriter/Credentials.h
Normal file
24
ESP32QRReaderDBWriter/Credentials.h
Normal file
@ -0,0 +1,24 @@
|
||||
/****************************************************************************************************************************
|
||||
Credentials.h
|
||||
Library for communicating with a MySQL or MariaDB Server
|
||||
|
||||
Based on and modified from Dr. Charles A. Bell's MySQL_Connector_Arduino Library https://github.com/ChuckBell/MySQL_Connector_Arduino
|
||||
to support nRF52, SAMD21/SAMD51, SAM DUE, STM32F/L/H/G/WB/MP1, ESP8266, ESP32, etc. boards using W5x00, ENC28J60, LAM8742A Ethernet,
|
||||
WiFiNINA, ESP-AT, built-in ESP8266/ESP32 WiFi.
|
||||
|
||||
The library provides simple and easy Client interface to MySQL or MariaDB Server.
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/MySQL_MariaDB_Generic
|
||||
Licensed under MIT license
|
||||
**********************************************************************************************************************************/
|
||||
|
||||
#ifndef Credentials_h
|
||||
#define Credentials_h
|
||||
|
||||
char ssid[] = "cpsNUCwifi"; // your network SSID (name)
|
||||
char pass[] = "ips999CPS"; // your network password
|
||||
|
||||
char user[] = "db_user"; // MySQL user login username
|
||||
char password[] = "db_password"; // MySQL user login password
|
||||
|
||||
#endif //Credentials_h
|
413
ESP32QRReaderDBWriter/ESP32QRReaderDBWriter.ino
Normal file
413
ESP32QRReaderDBWriter/ESP32QRReaderDBWriter.ino
Normal file
@ -0,0 +1,413 @@
|
||||
/*
|
||||
ESP32-CAM QR code Reader
|
||||
Author : ChungYi Fu (Kaohsiung, Taiwan) 2021-8-13 20:00
|
||||
https://www.facebook.com/francefu
|
||||
|
||||
Refer to the code
|
||||
https://github.com/alvarowolfx/ESP32QRCodeReader
|
||||
|
||||
自訂指令格式 http://192.168.xxx.xxx/control?cmd=P1;P2;P3;P4;P5;P6;P7;P8;P9
|
||||
|
||||
http://192.168.xxx.xxx/?ip //取得APIP, STAIP
|
||||
http://192.168.xxx.xxx/?mac //取得MAC位址
|
||||
http://192.168.xxx.xxx/?digitalwrite=pin;value //數位輸出
|
||||
http://192.168.xxx.xxx/?analogwrite=pin;value //類比輸出
|
||||
http://192.168.xxx.xxx/?digitalread=pin //數位讀取
|
||||
http://192.168.xxx.xxx/?analogread=pin //類比讀取
|
||||
http://192.168.xxx.xxx/?touchread=pin //觸碰讀取
|
||||
http://192.168.xxx.xxx/?restart //重啟電源
|
||||
http://192.168.xxx.xxx/?flash=value //閃光燈 value= 0~255
|
||||
http://192.168.xxx.xxx/?servo=pin;value //伺服馬達 value= 0~180
|
||||
http://192.168.xxx.xxx/?relay=pin;value //繼電器 value = 0, 1
|
||||
http://192.168.xxx.xxx/?uart=value //序列埠
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Serial.printf(); kann anscheinend keine Strings ausgeben, die länger als 13 Zeichen sind -> dadurch gehts: Serial.printf("Insertcommand: %s\n:", INSERT_SQL.c_str());
|
||||
|
||||
#include "esp_camera.h"
|
||||
//#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "quirc.h"
|
||||
|
||||
//Includes&defines etc für den MariaDB Entry ###########################################################
|
||||
#include "defines.h"
|
||||
#include "Credentials.h"
|
||||
|
||||
#include <MySQL_Generic.h>
|
||||
|
||||
#define USING_HOST_NAME false
|
||||
|
||||
#if USING_HOST_NAME
|
||||
// Optional using hostname, and Ethernet built-in DNS lookup
|
||||
char server[] = "your_account.ddns.net"; // change to your server's hostname/URL
|
||||
#else
|
||||
IPAddress server(10, 42, 0, 1);
|
||||
#endif
|
||||
|
||||
uint16_t server_port = 3306; //5698;
|
||||
|
||||
char default_database[] = "myTestDb"; //"test_arduino";
|
||||
char default_table[] = "myTestTable"; //"test_arduino";
|
||||
|
||||
String default_value = "defaultString";
|
||||
|
||||
// Sample query
|
||||
String INSERT_SQL = String("INSERT INTO ") + default_database + "." + default_table
|
||||
+ " (qrCodeText) VALUES ('" + default_value + "')";
|
||||
|
||||
|
||||
#define LED_BUILTIN 4 //die Zeile wird für das LED benötigt
|
||||
|
||||
|
||||
MySQL_Connection conn((Client *)&client);
|
||||
|
||||
MySQL_Query *query_mem;
|
||||
//Includes&defines etc für den MariaDB Entry - ENDE ####################################################
|
||||
|
||||
TaskHandle_t Task;
|
||||
|
||||
//ESP32-CAM
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 0
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 21
|
||||
#define Y4_GPIO_NUM 19
|
||||
#define Y3_GPIO_NUM 18
|
||||
#define Y2_GPIO_NUM 5
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
struct QRCodeData
|
||||
{
|
||||
bool valid;
|
||||
int dataType;
|
||||
uint8_t payload[1024];
|
||||
int payloadLen;
|
||||
};
|
||||
|
||||
struct quirc *q = NULL;
|
||||
uint8_t *image = NULL;
|
||||
camera_fb_t * fb = NULL;
|
||||
struct quirc_code code;
|
||||
struct quirc_data data;
|
||||
quirc_decode_error_t err;
|
||||
struct QRCodeData qrCodeData;
|
||||
String QRCodeResult = "";
|
||||
|
||||
|
||||
|
||||
camera_config_t config;
|
||||
|
||||
//###############################################################################################
|
||||
void setup() {
|
||||
//WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
|
||||
|
||||
Serial.begin(115200);
|
||||
//Serial.setDebugOutput(false);
|
||||
Serial.println();
|
||||
|
||||
Serial.println("--------------------------Starting the EPS32-QR-Code-Reader--------------------------");
|
||||
|
||||
pinMode(LED_BUILTIN, OUTPUT); //die Zeile wird für das LED benötigt
|
||||
|
||||
https://github.com/espressif/esp32-camera/blob/master/driver/include/esp_camera.h
|
||||
config.ledc_channel = LEDC_CHANNEL_0;
|
||||
config.ledc_timer = LEDC_TIMER_0;
|
||||
config.pin_d0 = Y2_GPIO_NUM;
|
||||
config.pin_d1 = Y3_GPIO_NUM;
|
||||
config.pin_d2 = Y4_GPIO_NUM;
|
||||
config.pin_d3 = Y5_GPIO_NUM;
|
||||
config.pin_d4 = Y6_GPIO_NUM;
|
||||
config.pin_d5 = Y7_GPIO_NUM;
|
||||
config.pin_d6 = Y8_GPIO_NUM;
|
||||
config.pin_d7 = Y9_GPIO_NUM;
|
||||
config.pin_xclk = XCLK_GPIO_NUM;
|
||||
config.pin_pclk = PCLK_GPIO_NUM;
|
||||
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||
config.pin_href = HREF_GPIO_NUM;
|
||||
config.pin_sscb_sda = SIOD_GPIO_NUM;
|
||||
config.pin_sscb_scl = SIOC_GPIO_NUM;
|
||||
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||
config.pin_reset = RESET_GPIO_NUM;
|
||||
config.xclk_freq_hz = 10000000;
|
||||
config.pixel_format = PIXFORMAT_GRAYSCALE;
|
||||
config.frame_size = FRAMESIZE_QVGA;
|
||||
config.jpeg_quality = 15;
|
||||
config.fb_count = 1;
|
||||
|
||||
|
||||
esp_err_t err = esp_camera_init(&config);
|
||||
if (err != ESP_OK) {
|
||||
Serial.printf("Camera init failed with error 0x%x", err);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
s->set_framesize(s, FRAMESIZE_QVGA);
|
||||
|
||||
|
||||
xTaskCreatePinnedToCore(
|
||||
QRCodeReader, // Task function.
|
||||
"Task", // name of task.
|
||||
10000, // Stack size of task
|
||||
NULL, // parameter of the task
|
||||
1, // priority of the task
|
||||
&Task, // Task handle to keep track of created task
|
||||
0); // pin task to core 0
|
||||
|
||||
//Serial.print("listenConnection running on core ");
|
||||
//Serial.println(xPortGetCoreID());
|
||||
|
||||
//Setup für insert in MariaDB #########################################################
|
||||
Serial.begin(115200);
|
||||
while (!Serial && millis() < 5000); // wait for serial port to connect
|
||||
|
||||
/* Infoausgabe
|
||||
MYSQL_DISPLAY1("\n starting QR-Code reader on", BOARD_NAME);
|
||||
MYSQL_DISPLAY(MYSQL_MARIADB_GENERIC_VERSION);
|
||||
*/
|
||||
|
||||
// Remember to initialize your WiFi module
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
/* Infoausgabe
|
||||
#if ( USING_WIFI_ESP8266_AT )
|
||||
MYSQL_DISPLAY("Using ESP8266_AT/ESP8266_AT_WebServer Library");
|
||||
#elif ( USING_WIFIESPAT_LIB )
|
||||
MYSQL_DISPLAY("Using WiFiEspAT Library");
|
||||
#endif
|
||||
*/
|
||||
|
||||
// initialize serial for ESP module
|
||||
EspSerial.begin(115200);
|
||||
// initialize ESP module
|
||||
WiFi.init(&EspSerial);
|
||||
|
||||
MYSQL_DISPLAY(F("WiFi shield init done"));
|
||||
|
||||
// check for the presence of the shield
|
||||
if (WiFi.status() == WL_NO_SHIELD)
|
||||
{
|
||||
MYSQL_DISPLAY(F("WiFi shield not present"));
|
||||
// don't continue
|
||||
while (true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Begin WiFi section
|
||||
Serial.printf("Connecting to %s. \n", ssid);
|
||||
//MYSQL_DISPLAY1("Connecting to", ssid);
|
||||
|
||||
//WiFi.begin(ssid, pass);
|
||||
WiFi.begin(ssid);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
delay(500);
|
||||
//MYSQL_DISPLAY0(".");
|
||||
|
||||
//ESP32-LED Output, dass es nicht mit dem WLAN verbunden ist
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// print out info about the connection:
|
||||
MYSQL_DISPLAY1("Connected to network. My IP address is:", WiFi.localIP());
|
||||
|
||||
MYSQL_DISPLAY3("Connecting to SQL Server @", server, ", Port =", server_port);
|
||||
MYSQL_DISPLAY5("User =", user, ", PW =", password, ", DB =", default_database);
|
||||
|
||||
|
||||
//ESP32-LED Output, dass es mit dem WLAN verbunden ist
|
||||
for(int i=0; i<3;i++){
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
delay(300);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Setup für insert in MariaDB - Ende #########################################################
|
||||
}
|
||||
|
||||
void ledOutputError(){
|
||||
|
||||
//ESP32 LED Ausgabe, dass etwas nicht funktioniert hat
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
delay(100);
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
delay(100);
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//###################################################################################
|
||||
void runInsert() // MariaDB-Insert-Funktion
|
||||
{
|
||||
// Initiate the query class instance
|
||||
MySQL_Query query_mem = MySQL_Query(&conn);
|
||||
|
||||
if (conn.connected())
|
||||
{
|
||||
MYSQL_DISPLAY(INSERT_SQL);
|
||||
|
||||
// Execute the query
|
||||
// KH, check if valid before fetching
|
||||
if ( !query_mem.execute(INSERT_SQL.c_str()) )
|
||||
{
|
||||
MYSQL_DISPLAY("Insert error");
|
||||
ledOutputError();
|
||||
}
|
||||
else
|
||||
{
|
||||
MYSQL_DISPLAY("Data Inserted.");
|
||||
|
||||
//ESP32 LED Ausgabe, dass etwas inserted wurde
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MYSQL_DISPLAY("Disconnected from Server. Can't insert.");
|
||||
ledOutputError();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//###############################################################################################----------------------------
|
||||
void loop() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void charToString(const char *str, String &dbInsertString){
|
||||
|
||||
dbInsertString = ""; //max Länge 13 Zeichen für eine Ausgabe in Serial.printf
|
||||
size_t len = strlen(str);
|
||||
dbInsertString.reserve(len);
|
||||
|
||||
for(size_t i=0;i<len;i++){
|
||||
dbInsertString += str[i];
|
||||
}
|
||||
|
||||
//Serial.printf("Ausgabe des Strings: %s\n",dbInsertString.c_str());
|
||||
}
|
||||
|
||||
|
||||
//###############################################################################################----------------------------
|
||||
void QRCodeReader( void * pvParameters ){
|
||||
/* Infoausgabe
|
||||
Serial.print("QRCodeReader running on core ");
|
||||
Serial.println(xPortGetCoreID());
|
||||
*/
|
||||
|
||||
while(1){
|
||||
q = quirc_new();
|
||||
if (q == NULL){
|
||||
Serial.print("can't create quirc object\r\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
fb = esp_camera_fb_get();
|
||||
if (!fb)
|
||||
{
|
||||
Serial.println("Camera capture failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
//Serial.printf("quirc_begin\r\n");
|
||||
quirc_resize(q, fb->width, fb->height);
|
||||
image = quirc_begin(q, NULL, NULL);
|
||||
//Serial.printf("Frame w h len: %d, %d, %d \r\n", fb->width, fb->height, fb->len);
|
||||
memcpy(image, fb->buf, fb->len);
|
||||
quirc_end(q);
|
||||
//Serial.printf("quirc_end\r\n");
|
||||
|
||||
int count = quirc_count(q);
|
||||
if (count > 0) {
|
||||
//Serial.println(count);
|
||||
quirc_extract(q, 0, &code);
|
||||
err = quirc_decode(&code, &data);
|
||||
|
||||
if (err){
|
||||
Serial.println("Decoding FAILED");
|
||||
QRCodeResult = "Decoding FAILED";
|
||||
} else {
|
||||
Serial.printf("Decoding successful:\n");
|
||||
dumpData(&data);
|
||||
|
||||
//MariaDb-part #################--------------------
|
||||
MYSQL_DISPLAY("Connecting...");
|
||||
|
||||
|
||||
if (conn.connectNonBlocking(server, server_port, user, password) != RESULT_FAIL)
|
||||
{
|
||||
delay(500);
|
||||
|
||||
char * str = (char *) &data.payload[0]; //nicht sicher ob man die Umwandlung braucht
|
||||
charToString(str,default_value);
|
||||
|
||||
INSERT_SQL = String("INSERT INTO ") + default_database + "." + default_table + " (qrCodeText) VALUES ('" + default_value + "')";
|
||||
//Serial.printf("Insertcommand: %s\n:", INSERT_SQL.c_str());
|
||||
|
||||
runInsert();
|
||||
conn.close(); // close the connection
|
||||
}
|
||||
else
|
||||
{
|
||||
MYSQL_DISPLAY("\nConnect failed. Trying again on next iteration.");
|
||||
ledOutputError();
|
||||
}
|
||||
|
||||
|
||||
//MYSQL_DISPLAY("\nSleeping...");
|
||||
MYSQL_DISPLAY("================================================");
|
||||
delay(2000); //um nicht den gleichen Eintrag sofort doppelt drinnen zu haben
|
||||
//MariaDb-part-Ende #################--------------------
|
||||
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
esp_camera_fb_return(fb);
|
||||
fb = NULL;
|
||||
image = NULL;
|
||||
quirc_destroy(q);
|
||||
}
|
||||
}
|
||||
|
||||
//###############################################################################################
|
||||
void dumpData(const struct quirc_data *data)
|
||||
{
|
||||
//Serial.printf("Version: %d\n", data->version);
|
||||
//Serial.printf("ECC level: %c\n", "MLHQ"[data->ecc_level]);
|
||||
//Serial.printf("Mask: %d\n", data->mask);
|
||||
//Serial.printf("Length: %d\n", data->payload_len);
|
||||
Serial.printf("Inhalt des QR-Codes: %s\n", data->payload);
|
||||
|
||||
}
|
16
ESP32QRReaderDBWriter/LICENSE
Normal file
16
ESP32QRReaderDBWriter/LICENSE
Normal file
@ -0,0 +1,16 @@
|
||||
quirc -- QR-code recognition library
|
||||
Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all
|
||||
copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
193
ESP32QRReaderDBWriter/README.md
Normal file
193
ESP32QRReaderDBWriter/README.md
Normal file
@ -0,0 +1,193 @@
|
||||
Quirc
|
||||
=====
|
||||
|
||||
QR codes are a type of high-density matrix barcodes, and quirc is a library for
|
||||
extracting and decoding them from images. It has several features which make it
|
||||
a good choice for this purpose:
|
||||
|
||||
* It is fast enough to be used with realtime video: extracting and decoding
|
||||
from VGA frame takes about 50 ms on a modern x86 core.
|
||||
|
||||
* It has a robust and tolerant recognition algorithm. It can correctly
|
||||
recognise and decode QR codes which are rotated and/or oblique to the camera.
|
||||
It can also distinguish and decode multiple codes within the same image.
|
||||
|
||||
* It is easy to use, with a simple API described in a single commented header
|
||||
file (see below for an overview).
|
||||
|
||||
* It is small and easily embeddable, with no dependencies other than standard C
|
||||
functions.
|
||||
|
||||
* It has a very small memory footprint: one byte per image pixel, plus a few kB
|
||||
per decoder object.
|
||||
|
||||
* It uses no global mutable state, and is safe to use in a multithreaded
|
||||
application.
|
||||
|
||||
* BSD-licensed, with almost no restrictions regarding use and/or modification.
|
||||
|
||||
The distribution comes with, in addition to the library, several test programs.
|
||||
While the core library is very portable, these programs have some additional
|
||||
dependencies. All of them require libjpeg, and two (`quirc-demo` and `inspect`)
|
||||
require SDL. The camera demos use Linux-specific APIs:
|
||||
|
||||
### quirc-demo
|
||||
|
||||
This is an real-time demo which requires a camera and a graphical display. The
|
||||
video stream is displayed on screen as it's received, and any QR codes
|
||||
recognised are highlighted in the image, with the decoded information both
|
||||
displayed on the image and printed on stdout.
|
||||
|
||||
### quirc-scanner
|
||||
|
||||
This program turns your camera into a barcode scanner. It's almost the same as
|
||||
the `demo` application, but it doesn't display the video stream, and thus
|
||||
doesn't require a graphical display.
|
||||
|
||||
### qrtest
|
||||
|
||||
This test is used to evaluate the performance of library. Given a directory
|
||||
tree containing a bunch of JPEG images, it will attempt to locate and decode QR
|
||||
codes in each image. Speed and success statistics are collected and printed on
|
||||
stdout.
|
||||
|
||||
### inspect
|
||||
|
||||
This test is used for debugging. Given a single JPEG image, it will display a
|
||||
diagram showing the internal state of the decoder as well as printing
|
||||
additional information on stdout.
|
||||
|
||||
Installation
|
||||
------------
|
||||
To build the library and associated demos/tests, type `make`. If you need to
|
||||
decode "large" image files build with `CFLAGS="-DQUIRC_MAX_REGIONS=65534" make`
|
||||
instead. Note that this will increase the memory usage, it is discouraged for
|
||||
low resource devices (i.e. embedded).
|
||||
|
||||
Type `make install` to install the library, header file and camera demos.
|
||||
|
||||
You can specify one or several of the following targets if you don't want, or
|
||||
are unable to build everything:
|
||||
|
||||
* libquirc.a
|
||||
* libquirc.so
|
||||
* qrtest
|
||||
* inspect
|
||||
* quirc-scanner
|
||||
* quirc-demo
|
||||
|
||||
Library use
|
||||
-----------
|
||||
All of the library's functionality is exposed through a single header file,
|
||||
which you should include:
|
||||
|
||||
```C
|
||||
#include <quirc.h>
|
||||
```
|
||||
|
||||
To decode images, you'll need to instantiate a `struct quirc` object, which is
|
||||
done with the `quirc_new` function. Later, when you no longer need to decode
|
||||
anything, you should release the allocated memory with `quirc_destroy`:
|
||||
|
||||
```C
|
||||
struct quirc *qr;
|
||||
|
||||
qr = quirc_new();
|
||||
if (!qr) {
|
||||
perror("Failed to allocate memory");
|
||||
abort();
|
||||
}
|
||||
|
||||
/* ... */
|
||||
|
||||
quirc_destroy(qr);
|
||||
```
|
||||
|
||||
Having obtained a decoder object, you need to set the image size that you'll be
|
||||
working with, which is done using `quirc_resize`:
|
||||
|
||||
```C
|
||||
if (quirc_resize(qr, 640, 480) < 0) {
|
||||
perror("Failed to allocate video memory");
|
||||
abort();
|
||||
}
|
||||
```
|
||||
|
||||
`quirc_resize` and `quirc_new` are the only library functions which allocate
|
||||
memory. If you plan to process a series of frames (or a video stream), you
|
||||
probably want to allocate and size a single decoder and hold onto it to process
|
||||
each frame.
|
||||
|
||||
Processing frames is done in two stages. The first stage is an
|
||||
image-recognition stage called identification, which takes a grayscale image
|
||||
and searches for QR codes. Using `quirc_begin` and `quirc_end`, you can feed a
|
||||
grayscale image directly into the buffer that `quirc` uses for image
|
||||
processing:
|
||||
|
||||
```C
|
||||
uint8_t *image;
|
||||
int w, h;
|
||||
|
||||
image = quirc_begin(qr, &w, &h);
|
||||
|
||||
/* Fill out the image buffer here.
|
||||
* image is a pointer to a w*h bytes.
|
||||
* One byte per pixel, w pixels per line, h lines in the buffer.
|
||||
*/
|
||||
|
||||
quirc_end(qr);
|
||||
```
|
||||
|
||||
Note that `quirc_begin` simply returns a pointer to a previously allocated
|
||||
buffer. The buffer will contain uninitialized data. After the call to
|
||||
`quirc_end`, the decoder holds a list of detected QR codes which can be queried
|
||||
via `quirc_count` and `quirc_extract`.
|
||||
|
||||
At this point, the second stage of processing occurs -- decoding. This is done
|
||||
via the call to `quirc_decode`, which is not associated with a decoder object.
|
||||
|
||||
```C
|
||||
int num_codes;
|
||||
int i;
|
||||
|
||||
/* We've previously fed an image to the decoder via
|
||||
* quirc_begin/quirc_end.
|
||||
*/
|
||||
|
||||
num_codes = quirc_count(qr);
|
||||
for (i = 0; i < num_codes; i++) {
|
||||
struct quirc_code code;
|
||||
struct quirc_data data;
|
||||
quirc_decode_error_t err;
|
||||
|
||||
quirc_extract(qr, i, &code);
|
||||
|
||||
/* Decoding stage */
|
||||
err = quirc_decode(&code, &data);
|
||||
if (err)
|
||||
printf("DECODE FAILED: %s\n", quirc_strerror(err));
|
||||
else
|
||||
printf("Data: %s\n", data.payload);
|
||||
}
|
||||
```
|
||||
|
||||
`quirc_code` and `quirc_data` are flat structures which don't need to be
|
||||
initialized or freed after use.
|
||||
|
||||
Copyright
|
||||
---------
|
||||
Copyright (C) 2010-2012 Daniel Beer <<dlbeer@gmail.com>>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all
|
||||
copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
85
ESP32QRReaderDBWriter/collections.c
Normal file
85
ESP32QRReaderDBWriter/collections.c
Normal file
@ -0,0 +1,85 @@
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2017 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "collections.h"
|
||||
#define CHAR_BITS (sizeof(char) * 8)
|
||||
#define CHAR_MASK (CHAR_BITS - 1)
|
||||
#define CHAR_SHIFT IM_LOG2(CHAR_MASK)
|
||||
|
||||
//////////
|
||||
// lifo //
|
||||
//////////
|
||||
|
||||
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len)
|
||||
{
|
||||
ptr->len = 0;
|
||||
ptr->size = size;
|
||||
ptr->data_len = data_len;
|
||||
ptr->data = (char *)ps_malloc(size * data_len);
|
||||
}
|
||||
|
||||
void lifo_alloc_all(lifo_t *ptr, size_t *size, size_t data_len)
|
||||
{
|
||||
ptr->data = (char *)ps_malloc(255);
|
||||
ptr->data_len = data_len;
|
||||
ptr->size = 255 / data_len;
|
||||
ptr->len = 0;
|
||||
*size = ptr->size;
|
||||
}
|
||||
|
||||
void lifo_free(lifo_t *ptr)
|
||||
{
|
||||
if (ptr->data)
|
||||
{
|
||||
free(ptr->data);
|
||||
}
|
||||
}
|
||||
|
||||
void lifo_clear(lifo_t *ptr)
|
||||
{
|
||||
ptr->len = 0;
|
||||
}
|
||||
|
||||
size_t lifo_size(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len;
|
||||
}
|
||||
|
||||
bool lifo_is_not_empty(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len;
|
||||
}
|
||||
|
||||
bool lifo_is_not_full(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len != ptr->size;
|
||||
}
|
||||
|
||||
void lifo_enqueue(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(ptr->data + (ptr->len * ptr->data_len), data, ptr->data_len);
|
||||
|
||||
ptr->len += 1;
|
||||
}
|
||||
|
||||
void lifo_dequeue(lifo_t *ptr, void *data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
memcpy(data, ptr->data + ((ptr->len - 1) * ptr->data_len), ptr->data_len);
|
||||
}
|
||||
|
||||
ptr->len -= 1;
|
||||
}
|
||||
|
||||
void lifo_poke(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(ptr->data + (ptr->len * ptr->data_len), data, ptr->data_len);
|
||||
}
|
||||
|
||||
void lifo_peek(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(data, ptr->data + ((ptr->len - 1) * ptr->data_len), ptr->data_len);
|
||||
}
|
33
ESP32QRReaderDBWriter/collections.h
Normal file
33
ESP32QRReaderDBWriter/collections.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2017 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef __COLLECTIONS_H__
|
||||
#define __COLLECTIONS_H__
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
//////////
|
||||
// lifo //
|
||||
//////////
|
||||
|
||||
typedef struct lifo
|
||||
{
|
||||
size_t len, size, data_len;
|
||||
char *data;
|
||||
}
|
||||
__attribute__((aligned(8))) lifo_t;
|
||||
|
||||
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len);
|
||||
void lifo_alloc_all(lifo_t *ptr, size_t *size, size_t data_len);
|
||||
void lifo_free(lifo_t *ptr);
|
||||
void lifo_clear(lifo_t *ptr);
|
||||
size_t lifo_size(lifo_t *ptr);
|
||||
bool lifo_is_not_empty(lifo_t *ptr);
|
||||
bool lifo_is_not_full(lifo_t *ptr);
|
||||
void lifo_enqueue(lifo_t *ptr, void *data);
|
||||
void lifo_dequeue(lifo_t *ptr, void *data);
|
||||
void lifo_poke(lifo_t *ptr, void *data);
|
||||
void lifo_peek(lifo_t *ptr, void *data);
|
||||
|
||||
#endif /* __COLLECTIONS_H__ */
|
983
ESP32QRReaderDBWriter/decode.c
Normal file
983
ESP32QRReaderDBWriter/decode.c
Normal file
@ -0,0 +1,983 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "quirc_internal.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_POLY 64
|
||||
|
||||
/************************************************************************
|
||||
* Galois fields
|
||||
*/
|
||||
|
||||
struct galois_field
|
||||
{
|
||||
int p;
|
||||
const uint8_t *log;
|
||||
const uint8_t *exp;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
static const uint8_t gf16_exp[16] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x03, 0x06, 0x0c, 0x0b,
|
||||
0x05, 0x0a, 0x07, 0x0e, 0x0f, 0x0d, 0x09, 0x01};
|
||||
|
||||
static const uint8_t gf16_log[16] = {
|
||||
0x00, 0x0f, 0x01, 0x04, 0x02, 0x08, 0x05, 0x0a,
|
||||
0x03, 0x0e, 0x09, 0x07, 0x06, 0x0d, 0x0b, 0x0c};
|
||||
|
||||
static const struct galois_field gf16 = {
|
||||
.p = 15,
|
||||
.log = gf16_log,
|
||||
.exp = gf16_exp};
|
||||
|
||||
static const uint8_t gf256_exp[256] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
|
||||
0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
|
||||
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
|
||||
0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
|
||||
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
|
||||
0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
|
||||
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
|
||||
0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
|
||||
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
|
||||
0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
|
||||
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
|
||||
0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
|
||||
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
|
||||
0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
|
||||
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
|
||||
0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
|
||||
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
|
||||
0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
|
||||
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
|
||||
0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
|
||||
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
|
||||
0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
|
||||
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
|
||||
0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
|
||||
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
|
||||
0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
|
||||
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
|
||||
0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
|
||||
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
|
||||
0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
|
||||
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
|
||||
0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01};
|
||||
|
||||
static const uint8_t gf256_log[256] = {
|
||||
0x00, 0xff, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
|
||||
0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
|
||||
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
|
||||
0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
|
||||
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
|
||||
0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
|
||||
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
|
||||
0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
|
||||
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
|
||||
0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
|
||||
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
|
||||
0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
|
||||
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
|
||||
0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
|
||||
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
|
||||
0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
|
||||
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
|
||||
0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
|
||||
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
|
||||
0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
|
||||
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
|
||||
0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
|
||||
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
|
||||
0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
|
||||
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
|
||||
0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
|
||||
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
|
||||
0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
|
||||
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
|
||||
0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
|
||||
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
|
||||
0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf};
|
||||
|
||||
const static struct galois_field gf256 = {
|
||||
.p = 255,
|
||||
.log = gf256_log,
|
||||
.exp = gf256_exp};
|
||||
|
||||
/************************************************************************
|
||||
* Polynomial operations
|
||||
*/
|
||||
|
||||
static void poly_add(uint8_t *dst, const uint8_t *src, uint8_t c,
|
||||
int shift, const struct galois_field *gf)
|
||||
{
|
||||
int i;
|
||||
int log_c = gf->log[c];
|
||||
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_POLY; i++)
|
||||
{
|
||||
int p = i + shift;
|
||||
uint8_t v = src[i];
|
||||
|
||||
if (p < 0 || p >= MAX_POLY)
|
||||
continue;
|
||||
if (!v)
|
||||
continue;
|
||||
|
||||
dst[p] ^= gf->exp[(gf->log[v] + log_c) % gf->p];
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t poly_eval(const uint8_t *s, uint8_t x,
|
||||
const struct galois_field *gf)
|
||||
{
|
||||
int i;
|
||||
uint8_t sum = 0;
|
||||
uint8_t log_x = gf->log[x];
|
||||
|
||||
if (!x)
|
||||
return s[0];
|
||||
|
||||
for (i = 0; i < MAX_POLY; i++)
|
||||
{
|
||||
uint8_t c = s[i];
|
||||
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
sum ^= gf->exp[(gf->log[c] + log_x * i) % gf->p];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Berlekamp-Massey algorithm for finding error locator polynomials.
|
||||
*/
|
||||
|
||||
static void berlekamp_massey(const uint8_t *s, int N,
|
||||
const struct galois_field *gf,
|
||||
uint8_t *sigma)
|
||||
{
|
||||
uint8_t C[MAX_POLY];
|
||||
uint8_t B[MAX_POLY];
|
||||
int L = 0;
|
||||
int m = 1;
|
||||
uint8_t b = 1;
|
||||
int n;
|
||||
|
||||
memset(B, 0, sizeof(B));
|
||||
memset(C, 0, sizeof(C));
|
||||
B[0] = 1;
|
||||
C[0] = 1;
|
||||
|
||||
for (n = 0; n < N; n++)
|
||||
{
|
||||
uint8_t d = s[n];
|
||||
uint8_t mult;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= L; i++)
|
||||
{
|
||||
if (!(C[i] && s[n - i]))
|
||||
continue;
|
||||
|
||||
d ^= gf->exp[(gf->log[C[i]] +
|
||||
gf->log[s[n - i]]) %
|
||||
gf->p];
|
||||
}
|
||||
|
||||
mult = gf->exp[(gf->p - gf->log[b] + gf->log[d]) % gf->p];
|
||||
|
||||
if (!d)
|
||||
{
|
||||
m++;
|
||||
}
|
||||
else if (L * 2 <= n)
|
||||
{
|
||||
uint8_t T[MAX_POLY];
|
||||
|
||||
memcpy(T, C, sizeof(T));
|
||||
poly_add(C, B, mult, m, gf);
|
||||
memcpy(B, T, sizeof(B));
|
||||
L = n + 1 - L;
|
||||
b = d;
|
||||
m = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
poly_add(C, B, mult, m, gf);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(sigma, C, MAX_POLY);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Code stream error correction
|
||||
*
|
||||
* Generator polynomial for GF(2^8) is x^8 + x^4 + x^3 + x^2 + 1
|
||||
*/
|
||||
|
||||
static int block_syndromes(const uint8_t *data, int bs, int npar, uint8_t *s)
|
||||
{
|
||||
int nonzero = 0;
|
||||
int i;
|
||||
|
||||
memset(s, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < npar; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < bs; j++)
|
||||
{
|
||||
uint8_t c = data[bs - j - 1];
|
||||
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
s[i] ^= gf256_exp[((int)gf256_log[c] +
|
||||
i * j) %
|
||||
255];
|
||||
}
|
||||
|
||||
if (s[i])
|
||||
nonzero = 1;
|
||||
}
|
||||
|
||||
return nonzero;
|
||||
}
|
||||
|
||||
static void eloc_poly(uint8_t *omega,
|
||||
const uint8_t *s, const uint8_t *sigma,
|
||||
int npar)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(omega, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < npar; i++)
|
||||
{
|
||||
const uint8_t a = sigma[i];
|
||||
const uint8_t log_a = gf256_log[a];
|
||||
int j;
|
||||
|
||||
if (!a)
|
||||
continue;
|
||||
|
||||
for (j = 0; j + 1 < MAX_POLY; j++)
|
||||
{
|
||||
const uint8_t b = s[j + 1];
|
||||
|
||||
if (i + j >= npar)
|
||||
break;
|
||||
|
||||
if (!b)
|
||||
continue;
|
||||
|
||||
omega[i + j] ^=
|
||||
gf256_exp[(log_a + gf256_log[b]) % 255];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static quirc_decode_error_t correct_block(uint8_t *data,
|
||||
const struct quirc_rs_params *ecc)
|
||||
{
|
||||
int npar = ecc->bs - ecc->dw;
|
||||
uint8_t s[MAX_POLY];
|
||||
uint8_t sigma[MAX_POLY];
|
||||
uint8_t sigma_deriv[MAX_POLY];
|
||||
uint8_t omega[MAX_POLY];
|
||||
int i;
|
||||
|
||||
/* Compute syndrome vector */
|
||||
if (!block_syndromes(data, ecc->bs, npar, s))
|
||||
return QUIRC_SUCCESS;
|
||||
|
||||
berlekamp_massey(s, npar, &gf256, sigma);
|
||||
|
||||
/* Compute derivative of sigma */
|
||||
memset(sigma_deriv, 0, MAX_POLY);
|
||||
for (i = 0; i + 1 < MAX_POLY; i += 2)
|
||||
sigma_deriv[i] = sigma[i + 1];
|
||||
|
||||
/* Compute error evaluator polynomial */
|
||||
eloc_poly(omega, s, sigma, npar - 1);
|
||||
|
||||
/* Find error locations and magnitudes */
|
||||
for (i = 0; i < ecc->bs; i++)
|
||||
{
|
||||
uint8_t xinv = gf256_exp[255 - i];
|
||||
|
||||
if (!poly_eval(sigma, xinv, &gf256))
|
||||
{
|
||||
uint8_t sd_x = poly_eval(sigma_deriv, xinv, &gf256);
|
||||
uint8_t omega_x = poly_eval(omega, xinv, &gf256);
|
||||
uint8_t error = gf256_exp[(255 - gf256_log[sd_x] +
|
||||
gf256_log[omega_x]) %
|
||||
255];
|
||||
|
||||
data[ecc->bs - i - 1] ^= error;
|
||||
}
|
||||
}
|
||||
|
||||
if (block_syndromes(data, ecc->bs, npar, s))
|
||||
return QUIRC_ERROR_DATA_ECC;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Format value error correction
|
||||
*
|
||||
* Generator polynomial for GF(2^4) is x^4 + x + 1
|
||||
*/
|
||||
|
||||
#define FORMAT_MAX_ERROR 3
|
||||
#define FORMAT_SYNDROMES (FORMAT_MAX_ERROR * 2)
|
||||
#define FORMAT_BITS 15
|
||||
|
||||
static int format_syndromes(uint16_t u, uint8_t *s)
|
||||
{
|
||||
int i;
|
||||
int nonzero = 0;
|
||||
|
||||
memset(s, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < FORMAT_SYNDROMES; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
s[i] = 0;
|
||||
for (j = 0; j < FORMAT_BITS; j++)
|
||||
if (u & (1 << j))
|
||||
s[i] ^= gf16_exp[((i + 1) * j) % 15];
|
||||
|
||||
if (s[i])
|
||||
nonzero = 1;
|
||||
}
|
||||
|
||||
return nonzero;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t correct_format(uint16_t *f_ret)
|
||||
{
|
||||
uint16_t u = *f_ret;
|
||||
int i;
|
||||
uint8_t s[MAX_POLY];
|
||||
uint8_t sigma[MAX_POLY];
|
||||
|
||||
/* Evaluate U (received codeword) at each of alpha_1 .. alpha_6
|
||||
* to get S_1 .. S_6 (but we index them from 0).
|
||||
*/
|
||||
if (!format_syndromes(u, s))
|
||||
return QUIRC_SUCCESS;
|
||||
|
||||
berlekamp_massey(s, FORMAT_SYNDROMES, &gf16, sigma);
|
||||
|
||||
/* Now, find the roots of the polynomial */
|
||||
for (i = 0; i < 15; i++)
|
||||
if (!poly_eval(sigma, gf16_exp[15 - i], &gf16))
|
||||
u ^= (1 << i);
|
||||
|
||||
if (format_syndromes(u, s))
|
||||
return QUIRC_ERROR_FORMAT_ECC;
|
||||
|
||||
*f_ret = u;
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Decoder algorithm
|
||||
*/
|
||||
|
||||
struct datastream
|
||||
{
|
||||
uint8_t raw[QUIRC_MAX_PAYLOAD];
|
||||
int data_bits;
|
||||
int ptr;
|
||||
|
||||
uint8_t data[QUIRC_MAX_PAYLOAD];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
static inline int grid_bit(const struct quirc_code *code, int x, int y)
|
||||
{
|
||||
int p = y * code->size + x;
|
||||
|
||||
return (code->cell_bitmap[p >> 3] >> (p & 7)) & 1;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t read_format(const struct quirc_code *code,
|
||||
struct quirc_data *data, int which)
|
||||
{
|
||||
int i;
|
||||
uint16_t format = 0;
|
||||
uint16_t fdata;
|
||||
quirc_decode_error_t err;
|
||||
|
||||
if (which)
|
||||
{
|
||||
for (i = 0; i < 7; i++)
|
||||
format = (format << 1) |
|
||||
grid_bit(code, 8, code->size - 1 - i);
|
||||
for (i = 0; i < 8; i++)
|
||||
format = (format << 1) |
|
||||
grid_bit(code, code->size - 8 + i, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const int xs[15] = {
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 4, 3, 2, 1, 0};
|
||||
static const int ys[15] = {
|
||||
0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 8, 8, 8, 8, 8};
|
||||
|
||||
for (i = 14; i >= 0; i--)
|
||||
format = (format << 1) | grid_bit(code, xs[i], ys[i]);
|
||||
}
|
||||
|
||||
format ^= 0x5412;
|
||||
|
||||
err = correct_format(&format);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
fdata = format >> 10;
|
||||
data->ecc_level = fdata >> 3;
|
||||
data->mask = fdata & 7;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static int mask_bit(int mask, int i, int j)
|
||||
{
|
||||
switch (mask)
|
||||
{
|
||||
case 0:
|
||||
return !((i + j) % 2);
|
||||
case 1:
|
||||
return !(i % 2);
|
||||
case 2:
|
||||
return !(j % 3);
|
||||
case 3:
|
||||
return !((i + j) % 3);
|
||||
case 4:
|
||||
return !(((i / 2) + (j / 3)) % 2);
|
||||
case 5:
|
||||
return !((i * j) % 2 + (i * j) % 3);
|
||||
case 6:
|
||||
return !(((i * j) % 2 + (i * j) % 3) % 2);
|
||||
case 7:
|
||||
return !(((i * j) % 3 + (i + j) % 2) % 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reserved_cell(int version, int i, int j)
|
||||
{
|
||||
const struct quirc_version_info *ver = &quirc_version_db[version];
|
||||
int size = version * 4 + 17;
|
||||
int ai = -1, aj = -1, a;
|
||||
|
||||
/* Finder + format: top left */
|
||||
if (i < 9 && j < 9)
|
||||
return 1;
|
||||
|
||||
/* Finder + format: bottom left */
|
||||
if (i + 8 >= size && j < 9)
|
||||
return 1;
|
||||
|
||||
/* Finder + format: top right */
|
||||
if (i < 9 && j + 8 >= size)
|
||||
return 1;
|
||||
|
||||
/* Exclude timing patterns */
|
||||
if (i == 6 || j == 6)
|
||||
return 1;
|
||||
|
||||
/* Exclude version info, if it exists. Version info sits adjacent to
|
||||
* the top-right and bottom-left finders in three rows, bounded by
|
||||
* the timing pattern.
|
||||
*/
|
||||
if (version >= 7)
|
||||
{
|
||||
if (i < 6 && j + 11 >= size)
|
||||
return 1;
|
||||
if (i + 11 >= size && j < 6)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Exclude alignment patterns */
|
||||
for (a = 0; a < QUIRC_MAX_ALIGNMENT && ver->apat[a]; a++)
|
||||
{
|
||||
int p = ver->apat[a];
|
||||
|
||||
if (abs(p - i) < 3)
|
||||
ai = a;
|
||||
if (abs(p - j) < 3)
|
||||
aj = a;
|
||||
}
|
||||
|
||||
if (ai >= 0 && aj >= 0)
|
||||
{
|
||||
a--;
|
||||
if (ai > 0 && ai < a)
|
||||
return 1;
|
||||
if (aj > 0 && aj < a)
|
||||
return 1;
|
||||
if (aj == a && ai == a)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void read_bit(const struct quirc_code *code,
|
||||
struct quirc_data *data,
|
||||
struct datastream *ds, int i, int j)
|
||||
{
|
||||
int bitpos = ds->data_bits & 7;
|
||||
int bytepos = ds->data_bits >> 3;
|
||||
int v = grid_bit(code, j, i);
|
||||
|
||||
if (mask_bit(data->mask, i, j))
|
||||
v ^= 1;
|
||||
|
||||
if (v)
|
||||
ds->raw[bytepos] |= (0x80 >> bitpos);
|
||||
|
||||
ds->data_bits++;
|
||||
}
|
||||
|
||||
static void read_data(const struct quirc_code *code,
|
||||
struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int y = code->size - 1;
|
||||
int x = code->size - 1;
|
||||
int dir = -1;
|
||||
|
||||
while (x > 0)
|
||||
{
|
||||
if (x == 6)
|
||||
x--;
|
||||
|
||||
if (!reserved_cell(data->version, y, x))
|
||||
read_bit(code, data, ds, y, x);
|
||||
|
||||
if (!reserved_cell(data->version, y, x - 1))
|
||||
read_bit(code, data, ds, y, x - 1);
|
||||
|
||||
y += dir;
|
||||
if (y < 0 || y >= code->size)
|
||||
{
|
||||
dir = -dir;
|
||||
x -= 2;
|
||||
y += dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static quirc_decode_error_t codestream_ecc(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
const struct quirc_version_info *ver =
|
||||
&quirc_version_db[data->version];
|
||||
const struct quirc_rs_params *sb_ecc = &ver->ecc[data->ecc_level];
|
||||
struct quirc_rs_params lb_ecc;
|
||||
const int lb_count =
|
||||
(ver->data_bytes - sb_ecc->bs * sb_ecc->ns) / (sb_ecc->bs + 1);
|
||||
const int bc = lb_count + sb_ecc->ns;
|
||||
const int ecc_offset = sb_ecc->dw * bc + lb_count;
|
||||
int dst_offset = 0;
|
||||
int i;
|
||||
|
||||
memcpy(&lb_ecc, sb_ecc, sizeof(lb_ecc));
|
||||
lb_ecc.dw++;
|
||||
lb_ecc.bs++;
|
||||
|
||||
for (i = 0; i < bc; i++)
|
||||
{
|
||||
uint8_t *dst = ds->data + dst_offset;
|
||||
const struct quirc_rs_params *ecc =
|
||||
(i < sb_ecc->ns) ? sb_ecc : &lb_ecc;
|
||||
const int num_ec = ecc->bs - ecc->dw;
|
||||
quirc_decode_error_t err;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < ecc->dw; j++)
|
||||
dst[j] = ds->raw[j * bc + i];
|
||||
for (j = 0; j < num_ec; j++)
|
||||
dst[ecc->dw + j] = ds->raw[ecc_offset + j * bc + i];
|
||||
|
||||
err = correct_block(dst, ecc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dst_offset += ecc->dw;
|
||||
}
|
||||
|
||||
ds->data_bits = dst_offset * 8;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int bits_remaining(const struct datastream *ds)
|
||||
{
|
||||
return ds->data_bits - ds->ptr;
|
||||
}
|
||||
|
||||
static int take_bits(struct datastream *ds, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (len && (ds->ptr < ds->data_bits))
|
||||
{
|
||||
uint8_t b = ds->data[ds->ptr >> 3];
|
||||
int bitpos = ds->ptr & 7;
|
||||
|
||||
ret <<= 1;
|
||||
if ((b << bitpos) & 0x80)
|
||||
ret |= 1;
|
||||
|
||||
ds->ptr++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int numeric_tuple(struct quirc_data *data,
|
||||
struct datastream *ds,
|
||||
int bits, int digits)
|
||||
{
|
||||
int tuple;
|
||||
int i;
|
||||
|
||||
if (bits_remaining(ds) < bits)
|
||||
return -1;
|
||||
|
||||
tuple = take_bits(ds, bits);
|
||||
|
||||
for (i = digits - 1; i >= 0; i--)
|
||||
{
|
||||
data->payload[data->payload_len + i] = tuple % 10 + '0';
|
||||
tuple /= 10;
|
||||
}
|
||||
|
||||
data->payload_len += digits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_numeric(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 14;
|
||||
int count;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 10;
|
||||
else if (data->version < 27)
|
||||
bits = 12;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
|
||||
while (count >= 3)
|
||||
{
|
||||
if (numeric_tuple(data, ds, 10, 3) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 3;
|
||||
}
|
||||
|
||||
if (count >= 2)
|
||||
{
|
||||
if (numeric_tuple(data, ds, 7, 2) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
if (numeric_tuple(data, ds, 4, 1) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count--;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static int alpha_tuple(struct quirc_data *data,
|
||||
struct datastream *ds,
|
||||
int bits, int digits)
|
||||
{
|
||||
int tuple;
|
||||
int i;
|
||||
|
||||
if (bits_remaining(ds) < bits)
|
||||
return -1;
|
||||
|
||||
tuple = take_bits(ds, bits);
|
||||
|
||||
for (i = 0; i < digits; i++)
|
||||
{
|
||||
static const char *alpha_map =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
|
||||
|
||||
data->payload[data->payload_len + digits - i - 1] =
|
||||
alpha_map[tuple % 45];
|
||||
tuple /= 45;
|
||||
}
|
||||
|
||||
data->payload_len += digits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_alpha(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 13;
|
||||
int count;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 9;
|
||||
else if (data->version < 27)
|
||||
bits = 11;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
|
||||
while (count >= 2)
|
||||
{
|
||||
if (alpha_tuple(data, ds, 11, 2) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
if (alpha_tuple(data, ds, 6, 1) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count--;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_byte(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 16;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 8;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
if (bits_remaining(ds) < count * 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
data->payload[data->payload_len++] = take_bits(ds, 8);
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_kanji(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 12;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 8;
|
||||
else if (data->version < 27)
|
||||
bits = 10;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count * 2 + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
if (bits_remaining(ds) < count * 13)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
int d = take_bits(ds, 13);
|
||||
int msB = d / 0xc0;
|
||||
int lsB = d % 0xc0;
|
||||
int intermediate = (msB << 8) | lsB;
|
||||
uint16_t sjw;
|
||||
|
||||
if (intermediate + 0x8140 <= 0x9ffc)
|
||||
{
|
||||
/* bytes are in the range 0x8140 to 0x9FFC */
|
||||
sjw = intermediate + 0x8140;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bytes are in the range 0xE040 to 0xEBBF */
|
||||
sjw = intermediate + 0xc140;
|
||||
}
|
||||
|
||||
data->payload[data->payload_len++] = sjw >> 8;
|
||||
data->payload[data->payload_len++] = sjw & 0xff;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_eci(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
if (bits_remaining(ds) < 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = take_bits(ds, 8);
|
||||
|
||||
if ((data->eci & 0xc0) == 0x80)
|
||||
{
|
||||
if (bits_remaining(ds) < 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = (data->eci << 8) | take_bits(ds, 8);
|
||||
}
|
||||
else if ((data->eci & 0xe0) == 0xc0)
|
||||
{
|
||||
if (bits_remaining(ds) < 16)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = (data->eci << 16) | take_bits(ds, 16);
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_payload(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
while (bits_remaining(ds) >= 4)
|
||||
{
|
||||
quirc_decode_error_t err = QUIRC_SUCCESS;
|
||||
int type = take_bits(ds, 4);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case QUIRC_DATA_TYPE_NUMERIC:
|
||||
err = decode_numeric(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_ALPHA:
|
||||
err = decode_alpha(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_BYTE:
|
||||
err = decode_byte(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_KANJI:
|
||||
err = decode_kanji(data, ds);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
err = decode_eci(data, ds);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!(type & (type - 1)) && (type > data->data_type))
|
||||
data->data_type = type;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
/* Add nul terminator to all payloads */
|
||||
if (data->payload_len >= sizeof(data->payload))
|
||||
data->payload_len--;
|
||||
data->payload[data->payload_len] = 0;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
||||
struct quirc_data *data)
|
||||
{
|
||||
quirc_decode_error_t err;
|
||||
struct datastream *ds = ps_malloc(sizeof(struct datastream));
|
||||
|
||||
if ((code->size - 17) % 4)
|
||||
{
|
||||
free(ds);
|
||||
return QUIRC_ERROR_INVALID_GRID_SIZE;
|
||||
}
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
memset(ds, 0, sizeof(*ds));
|
||||
|
||||
data->version = (code->size - 17) / 4;
|
||||
|
||||
if (data->version < 1 ||
|
||||
data->version > QUIRC_MAX_VERSION)
|
||||
{
|
||||
free(ds);
|
||||
return QUIRC_ERROR_INVALID_VERSION;
|
||||
}
|
||||
|
||||
/* Read format information -- try both locations */
|
||||
err = read_format(code, data, 0);
|
||||
if (err)
|
||||
err = read_format(code, data, 1);
|
||||
if (err)
|
||||
{
|
||||
free(ds);
|
||||
return err;
|
||||
}
|
||||
|
||||
read_data(code, data, ds);
|
||||
err = codestream_ecc(data, ds);
|
||||
if (err)
|
||||
{
|
||||
free(ds);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = decode_payload(data, ds);
|
||||
if (err)
|
||||
{
|
||||
free(ds);
|
||||
return err;
|
||||
}
|
||||
|
||||
free(ds);
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
381
ESP32QRReaderDBWriter/defines.h
Normal file
381
ESP32QRReaderDBWriter/defines.h
Normal file
@ -0,0 +1,381 @@
|
||||
/****************************************************************************************************************************
|
||||
defines.h
|
||||
Library for communicating with a MySQL or MariaDB Server
|
||||
|
||||
Based on and modified from Dr. Charles A. Bell's MySQL_Connector_Arduino Library https://github.com/ChuckBell/MySQL_Connector_Arduino
|
||||
to support nRF52, SAMD21/SAMD51, SAM DUE, STM32F/L/H/G/WB/MP1, ESP8266, ESP32, etc. boards using W5x00, ENC28J60, LAM8742A Ethernet,
|
||||
WiFiNINA, ESP-AT, built-in ESP8266/ESP32 WiFi.
|
||||
|
||||
The library provides simple and easy Client interface to MySQL or MariaDB Server.
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/MySQL_MariaDB_Generic
|
||||
Licensed under MIT license
|
||||
**********************************************************************************************************************************/
|
||||
|
||||
#ifndef defines_h
|
||||
#define defines_h
|
||||
|
||||
#define DEBUG_ESP8266_AT_WEBSERVER_PORT Serial
|
||||
|
||||
// Debug Level from 0 to 4
|
||||
#define _ESP_AT_LOGLEVEL_ 1
|
||||
|
||||
#define MYSQL_DEBUG_PORT Serial
|
||||
|
||||
// Debug Level from 0 to 4
|
||||
#define _MYSQL_LOGLEVEL_ 1
|
||||
|
||||
#if ! (ESP8266 || ESP32 )
|
||||
// Select only one of these libraries, only for boards other than ESP8266/ESP32
|
||||
#define USING_WIFI_ESP8266_AT false
|
||||
#define USING_WIFININA_GENERIC false
|
||||
#define USING_WIFININA false
|
||||
#define USING_WIFIESPAT_LIB true
|
||||
#define USING_WIFI_CUSTOM false
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_SAMD_MKR1000)
|
||||
#if defined(USE_WIFI_NINA)
|
||||
#undef USE_WIFI_NINA
|
||||
#endif
|
||||
#define USE_WIFI_NINA false
|
||||
#define USE_WIFI101 true
|
||||
#endif
|
||||
|
||||
#if ( defined(NRF52840_FEATHER) || defined(NRF52832_FEATHER) || defined(NRF52_SERIES) || defined(ARDUINO_NRF52_ADAFRUIT) || \
|
||||
defined(NRF52840_FEATHER_SENSE) || defined(NRF52840_ITSYBITSY) || defined(NRF52840_CIRCUITPLAY) || defined(NRF52840_CLUE) || \
|
||||
defined(NRF52840_METRO) || defined(NRF52840_PCA10056) || defined(PARTICLE_XENON) || defined(NINA_B302_ublox) || defined(NINA_B112_ublox) )
|
||||
#if defined(WIFI_USE_NRF528XX)
|
||||
#undef WIFI_USE_NRF528XX
|
||||
#endif
|
||||
#define WIFI_USE_NRF528XX true
|
||||
#endif
|
||||
|
||||
#if ( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
|
||||
|| defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
|
||||
|| defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(__SAMD21G18A__) \
|
||||
|| defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD21E18A__) || defined(__SAMD51__) || defined(__SAMD51J20A__) || defined(__SAMD51J19A__) \
|
||||
|| defined(__SAMD51G19A__) || defined(__SAMD51P19A__) || defined(__SAMD21G18A__) )
|
||||
#if defined(WIFI_USE_SAMD)
|
||||
#undef WIFI_USE_SAMD
|
||||
#endif
|
||||
#define WIFI_USE_SAMD true
|
||||
#endif
|
||||
|
||||
#if ( defined(ARDUINO_SAM_DUE) || defined(__SAM3X8E__) )
|
||||
#if defined(WIFI_USE_SAM_DUE)
|
||||
#undef WIFI_USE_SAM_DUE
|
||||
#endif
|
||||
#define WIFI_USE_SAM_DUE true
|
||||
#warning Use SAM_DUE architecture
|
||||
#endif
|
||||
|
||||
#if ( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) ||defined(STM32F4) || defined(STM32F7) || \
|
||||
defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7) ||defined(STM32G0) || defined(STM32G4) || \
|
||||
defined(STM32WB) || defined(STM32MP1) )
|
||||
#if defined(WIFI_USE_STM32)
|
||||
#undef WIFI_USE_STM32
|
||||
#endif
|
||||
#define WIFI_USE_STM32 true
|
||||
#endif
|
||||
|
||||
#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_RASPBERRY_PI_PICO) || \
|
||||
defined(ARDUINO_GENERIC_RP2040) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) )
|
||||
#if defined(WIFI_USE_RP2040)
|
||||
#undef WIFI_USE_RP2040
|
||||
#endif
|
||||
#define WIFI_USE_RP2040 true
|
||||
#endif
|
||||
|
||||
#ifdef CORE_TEENSY
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
// For Teensy 4.1/4.0
|
||||
#define EspSerial Serial2 //Serial2, Pin RX2 : 7, TX2 : 8
|
||||
#endif
|
||||
|
||||
#if defined(__IMXRT1062__)
|
||||
// For Teensy 4.1/4.0
|
||||
#define BOARD_TYPE "TEENSY 4.1/4.0"
|
||||
#elif defined(__MK66FX1M0__)
|
||||
#define BOARD_TYPE "Teensy 3.6"
|
||||
#elif defined(__MK64FX512__)
|
||||
#define BOARD_TYPE "Teensy 3.5"
|
||||
#elif defined(__MKL26Z64__)
|
||||
#define BOARD_TYPE "Teensy LC"
|
||||
#elif defined(__MK20DX256__)
|
||||
#define BOARD_TYPE "Teensy 3.2" // and Teensy 3.1 (obsolete)
|
||||
#elif defined(__MK20DX128__)
|
||||
#define BOARD_TYPE "Teensy 3.0"
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
#error Teensy 2.0++ not supported yet
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#error Teensy 2.0 not supported yet
|
||||
#else
|
||||
// For Other Boards
|
||||
#define BOARD_TYPE "Unknown Teensy Board"
|
||||
#endif
|
||||
|
||||
#elif defined(WIFI_USE_NRF528XX)
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#if defined(NRF52840_FEATHER)
|
||||
#define BOARD_TYPE "NRF52840_FEATHER_EXPRESS"
|
||||
#elif defined(NRF52832_FEATHER)
|
||||
#define BOARD_TYPE "NRF52832_FEATHER"
|
||||
#elif defined(NRF52840_FEATHER_SENSE)
|
||||
#define BOARD_TYPE "NRF52840_FEATHER_SENSE"
|
||||
#elif defined(NRF52840_ITSYBITSY)
|
||||
#define BOARD_TYPE "NRF52840_ITSYBITSY_EXPRESS"
|
||||
#elif defined(NRF52840_CIRCUITPLAY)
|
||||
#define BOARD_TYPE "NRF52840_CIRCUIT_PLAYGROUND"
|
||||
#elif defined(NRF52840_CLUE)
|
||||
#define BOARD_TYPE "NRF52840_CLUE"
|
||||
#elif defined(NRF52840_METRO)
|
||||
#define BOARD_TYPE "NRF52840_METRO_EXPRESS"
|
||||
#elif defined(NRF52840_PCA10056)
|
||||
#define BOARD_TYPE "NORDIC_NRF52840DK"
|
||||
#elif defined(NINA_B302_ublox)
|
||||
#define BOARD_TYPE "NINA_B302_ublox"
|
||||
#elif defined(NINA_B112_ublox)
|
||||
#define BOARD_TYPE "NINA_B112_ublox"
|
||||
#elif defined(PARTICLE_XENON)
|
||||
#define BOARD_TYPE "PARTICLE_XENON"
|
||||
#elif defined(MDBT50Q_RX)
|
||||
#define BOARD_TYPE "RAYTAC_MDBT50Q_RX"
|
||||
#elif defined(ARDUINO_NRF52_ADAFRUIT)
|
||||
#define BOARD_TYPE "ARDUINO_NRF52_ADAFRUIT"
|
||||
#else
|
||||
#define BOARD_TYPE "nRF52 Unknown"
|
||||
#endif
|
||||
|
||||
#elif defined(WIFI_USE_SAMD)
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
// For SAMD
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_SAMD_ZERO)
|
||||
#define BOARD_TYPE "SAMD Zero"
|
||||
#elif defined(ARDUINO_SAMD_MKR1000)
|
||||
#define BOARD_TYPE "SAMD MKR1000"
|
||||
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
|
||||
#define BOARD_TYPE "SAMD MKRWIFI1010"
|
||||
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
|
||||
#define BOARD_TYPE "SAMD NANO_33_IOT"
|
||||
#elif defined(ARDUINO_SAMD_MKRFox1200)
|
||||
#define BOARD_TYPE "SAMD MKRFox1200"
|
||||
#elif ( defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) )
|
||||
#define BOARD_TYPE "SAMD MKRWAN13X0"
|
||||
#elif defined(ARDUINO_SAMD_MKRGSM1400)
|
||||
#define BOARD_TYPE "SAMD MKRGSM1400"
|
||||
#elif defined(ARDUINO_SAMD_MKRNB1500)
|
||||
#define BOARD_TYPE "SAMD MKRNB1500"
|
||||
#elif defined(ARDUINO_SAMD_MKRVIDOR4000)
|
||||
#define BOARD_TYPE "SAMD MKRVIDOR4000"
|
||||
#elif defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS"
|
||||
#elif defined(ADAFRUIT_FEATHER_M0_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_FEATHER_M0_EXPRESS"
|
||||
#elif defined(ADAFRUIT_METRO_M0_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_METRO_M0_EXPRESS"
|
||||
#elif defined(ADAFRUIT_CIRCUITPLAYGROUND_M0)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_CIRCUITPLAYGROUND_M0"
|
||||
#elif defined(ADAFRUIT_GEMMA_M0)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_GEMMA_M0"
|
||||
#elif defined(ADAFRUIT_TRINKET_M0)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_TRINKET_M0"
|
||||
#elif defined(ADAFRUIT_ITSYBITSY_M0)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_ITSYBITSY_M0"
|
||||
#elif defined(ARDUINO_SAMD_HALLOWING_M0)
|
||||
#define BOARD_TYPE "SAMD21 ARDUINO_SAMD_HALLOWING_M0"
|
||||
#elif defined(ADAFRUIT_METRO_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_METRO_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_GRAND_CENTRAL_M4)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_GRAND_CENTRAL_M4"
|
||||
#elif defined(ADAFRUIT_FEATHER_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_FEATHER_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_ITSYBITSY_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_ITSYBITSY_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_TRELLIS_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_TRELLIS_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_PYPORTAL)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYPORTAL"
|
||||
#elif defined(ADAFRUIT_PYPORTAL_M4_TITANO)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYPORTAL_M4_TITANO"
|
||||
#elif defined(ADAFRUIT_PYBADGE_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYBADGE_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_METRO_M4_AIRLIFT_LITE"
|
||||
#elif defined(ADAFRUIT_PYGAMER_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYGAMER_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_PYGAMER_ADVANCE_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYGAMER_ADVANCE_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_PYBADGE_AIRLIFT_M4)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYBADGE_AIRLIFT_M4"
|
||||
#elif defined(ADAFRUIT_MONSTER_M4SK_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_MONSTER_M4SK_EXPRESS"
|
||||
#elif defined(ADAFRUIT_HALLOWING_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_HALLOWING_M4_EXPRESS"
|
||||
#elif defined(SEEED_WIO_TERMINAL)
|
||||
#define BOARD_TYPE "SAMD SEEED_WIO_TERMINAL"
|
||||
#elif defined(SEEED_FEMTO_M0)
|
||||
#define BOARD_TYPE "SAMD SEEED_FEMTO_M0"
|
||||
#elif defined(SEEED_XIAO_M0)
|
||||
#define BOARD_TYPE "SAMD SEEED_XIAO_M0"
|
||||
#elif defined(Wio_Lite_MG126)
|
||||
#define BOARD_TYPE "SAMD SEEED Wio_Lite_MG126"
|
||||
#elif defined(WIO_GPS_BOARD)
|
||||
#define BOARD_TYPE "SAMD SEEED WIO_GPS_BOARD"
|
||||
#elif defined(SEEEDUINO_ZERO)
|
||||
#define BOARD_TYPE "SAMD SEEEDUINO_ZERO"
|
||||
#elif defined(SEEEDUINO_LORAWAN)
|
||||
#define BOARD_TYPE "SAMD SEEEDUINO_LORAWAN"
|
||||
#elif defined(SEEED_GROVE_UI_WIRELESS)
|
||||
#define BOARD_TYPE "SAMD SEEED_GROVE_UI_WIRELESS"
|
||||
#elif defined(__SAMD21E18A__)
|
||||
#define BOARD_TYPE "SAMD21E18A"
|
||||
#elif defined(__SAMD21G18A__)
|
||||
#define BOARD_TYPE "SAMD21G18A"
|
||||
#elif defined(__SAMD51G19A__)
|
||||
#define BOARD_TYPE "SAMD51G19A"
|
||||
#elif defined(__SAMD51J19A__)
|
||||
#define BOARD_TYPE "SAMD51J19A"
|
||||
#elif defined(__SAMD51P19A__)
|
||||
#define BOARD_TYPE "__SAMD51P19A__"
|
||||
#elif defined(__SAMD51J20A__)
|
||||
#define BOARD_TYPE "SAMD51J20A"
|
||||
#elif defined(__SAM3X8E__)
|
||||
#define BOARD_TYPE "SAM3X8E"
|
||||
#elif defined(__CPU_ARC__)
|
||||
#define BOARD_TYPE "CPU_ARC"
|
||||
#elif defined(__SAMD51__)
|
||||
#define BOARD_TYPE "SAMD51"
|
||||
#else
|
||||
#define BOARD_TYPE "SAMD Unknown"
|
||||
#endif
|
||||
|
||||
#elif defined(WIFI_USE_STM32)
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
// For STM32
|
||||
#if defined(ARDUINO_NUCLEO_F767ZI)
|
||||
#warning Nucleo-144 NUCLEO_F767ZI board selected, using HardwareSerial Serial1 @ pin D0/RX and D1/TX
|
||||
// RX TX
|
||||
HardwareSerial Serial1(D0, D1);
|
||||
#elif defined(ARDUINO_NUCLEO_L053R8)
|
||||
#warning Nucleo-64 NUCLEO_L053R8 board selected, using HardwareSerial Serial1 @ pin D0/RX and D1/TX
|
||||
// RX TX
|
||||
HardwareSerial Serial1(D0, D1); // (PA3, PA2);
|
||||
#endif
|
||||
|
||||
#warning EspSerial using SERIAL_PORT_HARDWARE, can be Serial or Serial1. See your board variant.h
|
||||
#define EspSerial SERIAL_PORT_HARDWARE //Serial1
|
||||
#endif
|
||||
|
||||
#if defined(STM32F0)
|
||||
#warning STM32F0 board selected
|
||||
#define BOARD_TYPE "STM32F0"
|
||||
#elif defined(STM32F1)
|
||||
#warning STM32F1 board selected
|
||||
#define BOARD_TYPE "STM32F1"
|
||||
#elif defined(STM32F2)
|
||||
#warning STM32F2 board selected
|
||||
#define BOARD_TYPE "STM32F2"
|
||||
#elif defined(STM32F3)
|
||||
#warning STM32F3 board selected
|
||||
#define BOARD_TYPE "STM32F3"
|
||||
#elif defined(STM32F4)
|
||||
#warning STM32F4 board selected
|
||||
#define BOARD_TYPE "STM32F4"
|
||||
#elif defined(STM32F7)
|
||||
#warning STM32F7 board selected
|
||||
#define BOARD_TYPE "STM32F7"
|
||||
#elif defined(STM32L0)
|
||||
#warning STM32L0 board selected
|
||||
#define BOARD_TYPE "STM32L0"
|
||||
#elif defined(STM32L1)
|
||||
#warning STM32L1 board selected
|
||||
#define BOARD_TYPE "STM32L1"
|
||||
#elif defined(STM32L4)
|
||||
#warning STM32L4 board selected
|
||||
#define BOARD_TYPE "STM32L4"
|
||||
#elif defined(STM32H7)
|
||||
#warning STM32H7 board selected
|
||||
#define BOARD_TYPE "STM32H7"
|
||||
#elif defined(STM32G0)
|
||||
#warning STM32G0 board selected
|
||||
#define BOARD_TYPE "STM32G0"
|
||||
#elif defined(STM32G4)
|
||||
#warning STM32G4 board selected
|
||||
#define BOARD_TYPE "STM32G4"
|
||||
#elif defined(STM32WB)
|
||||
#warning STM32WB board selected
|
||||
#define BOARD_TYPE "STM32WB"
|
||||
#elif defined(STM32MP1)
|
||||
#warning STM32MP1 board selected
|
||||
#define BOARD_TYPE "STM32MP1"
|
||||
#else
|
||||
#warning STM32 unknown board selected
|
||||
#define BOARD_TYPE "STM32 Unknown"
|
||||
#endif
|
||||
|
||||
#elif (ESP8266)
|
||||
#warning ESP8266 board selected
|
||||
#define BOARD_TYPE ARDUINO_BOARD
|
||||
|
||||
#elif (ESP32)
|
||||
#warning ESP32 board selected
|
||||
#define BOARD_TYPE ARDUINO_BOARD
|
||||
|
||||
#elif defined(WIFI_USE_RP2040) && !defined(ARDUINO_ARCH_MBED)
|
||||
|
||||
// For RP2040
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#elif defined(WIFI_USE_RP2040) && defined(ARDUINO_ARCH_MBED)
|
||||
|
||||
#warning Using ARDUINO_ARCH_MBED
|
||||
|
||||
// For MBED RP2040
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_RASPBERRY_PI_PICO) || \
|
||||
defined(ARDUINO_GENERIC_RP2040) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) )
|
||||
// Only undef known BOARD_NAME to use better one
|
||||
#undef BOARD_NAME
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_RASPBERRY_PI_PICO)
|
||||
#define BOARD_NAME "MBED RASPBERRY_PI_PICO"
|
||||
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
|
||||
#define BOARD_NAME "MBED ADAFRUIT_FEATHER_RP2040"
|
||||
#elif defined(ARDUINO_GENERIC_RP2040)
|
||||
#define BOARD_NAME "MBED GENERIC_RP2040"
|
||||
#elif defined(ARDUINO_NANO_RP2040_CONNECT)
|
||||
#define BOARD_NAME "MBED NANO_RP2040_CONNECT"
|
||||
#else
|
||||
// Use default BOARD_NAME if exists
|
||||
#if !defined(BOARD_NAME)
|
||||
#define BOARD_NAME "MBED Unknown RP2040"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
// For Mega
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#define BOARD_TYPE "AVR Mega"
|
||||
#endif
|
||||
|
||||
#ifndef BOARD_NAME
|
||||
#define BOARD_NAME BOARD_TYPE
|
||||
#endif
|
||||
|
||||
#endif //defines_h
|
70
ESP32QRReaderDBWriter/fmath.h
Normal file
70
ESP32QRReaderDBWriter/fmath.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Fast approximate math functions.
|
||||
*
|
||||
*/
|
||||
#ifndef __FMATH_H
|
||||
#define __FMATH_H
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
static inline float fast_sqrtf(float x)
|
||||
{
|
||||
//return sqrtf(x);
|
||||
asm("fsqrt.s %0, %1"
|
||||
: "=f"(x)
|
||||
: "f"(x));
|
||||
return x;
|
||||
}
|
||||
static inline int fast_floorf(float x)
|
||||
{
|
||||
return (int)(x);
|
||||
}
|
||||
|
||||
static inline int fast_ceilf(float x)
|
||||
{
|
||||
return (int)(x + 0.9999f);
|
||||
}
|
||||
|
||||
static inline int fast_roundf(float x)
|
||||
{
|
||||
return (int)(x);
|
||||
}
|
||||
|
||||
static inline float fast_fabsf(float d)
|
||||
{
|
||||
return fabsf(d);
|
||||
}
|
||||
|
||||
extern int fast_floorf(float x);
|
||||
extern int fast_ceilf(float x);
|
||||
extern int fast_roundf(float x);
|
||||
extern float fast_atanf(float x);
|
||||
extern float fast_atan2f(float y, float x);
|
||||
extern float fast_expf(float x);
|
||||
extern float fast_cbrtf(float d);
|
||||
extern float fast_fabsf(float d);
|
||||
extern float fast_log(float x);
|
||||
extern float fast_log2(float x);
|
||||
extern float fast_powf(float a, float b);
|
||||
|
||||
/*#define fast_sqrtf(x) (sqrtf(x))
|
||||
#define fast_floorf(x) ((int)floorf(x))
|
||||
#define fast_ceilf(x) ((int)ceilf(x))
|
||||
#define fast_roundf(x) ((int)roundf(x))
|
||||
#define fast_atanf(x) (atanf(x))
|
||||
#define fast_atan2f(x,y) (atan2f((x),(y)))
|
||||
#define fast_expf(x) (expf(x))
|
||||
#define fast_cbrtf(x) (cbrtf(x))
|
||||
#define fast_fabsf(x) (fabsf(x))
|
||||
#define fast_log(x) (log(x))
|
||||
#define fast_log2(x) (log2(x))
|
||||
#define fast_powf(x,y) (powf((x),(y)))
|
||||
*/
|
||||
|
||||
extern const float cos_table[360];
|
||||
extern const float sin_table[360];
|
||||
#endif // __FMATH_H
|
1286
ESP32QRReaderDBWriter/identify.c
Normal file
1286
ESP32QRReaderDBWriter/identify.c
Normal file
File diff suppressed because it is too large
Load Diff
104
ESP32QRReaderDBWriter/quirc.c
Normal file
104
ESP32QRReaderDBWriter/quirc.c
Normal file
@ -0,0 +1,104 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "quirc_internal.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
const char *quirc_version(void)
|
||||
{
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
//static struct quirc _q;
|
||||
struct quirc *quirc_new(void)
|
||||
{
|
||||
struct quirc *q = ps_malloc(sizeof(*q));
|
||||
|
||||
if (!q)
|
||||
return NULL;
|
||||
|
||||
memset(q, 0, sizeof(*q));
|
||||
return q;
|
||||
}
|
||||
|
||||
void quirc_destroy(struct quirc *q)
|
||||
{
|
||||
if (q->image)
|
||||
if (q->image)
|
||||
free(q->image);
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
if (q->pixels)
|
||||
free(q->pixels);
|
||||
|
||||
if (q)
|
||||
free(q);
|
||||
}
|
||||
|
||||
//static quirc_pixel_t img_buf[320*240];
|
||||
int quirc_resize(struct quirc *q, int w, int h)
|
||||
{
|
||||
if (q->image)
|
||||
{
|
||||
free(q->image);
|
||||
}
|
||||
uint8_t *new_image = ps_malloc(w * h);
|
||||
|
||||
if (!new_image)
|
||||
return -1;
|
||||
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
{ //should gray, 1==1
|
||||
size_t new_size = w * h * sizeof(quirc_pixel_t);
|
||||
if (q->pixels)
|
||||
free(q->pixels);
|
||||
quirc_pixel_t *new_pixels = ps_malloc(new_size);
|
||||
if (!new_pixels)
|
||||
{
|
||||
free(new_image);
|
||||
return -1;
|
||||
}
|
||||
q->pixels = new_pixels;
|
||||
}
|
||||
q->image = new_image;
|
||||
q->w = w;
|
||||
q->h = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int quirc_count(const struct quirc *q)
|
||||
{
|
||||
return q->num_grids;
|
||||
}
|
||||
|
||||
static const char *const error_table[] = {
|
||||
[QUIRC_SUCCESS] = "Success",
|
||||
[QUIRC_ERROR_INVALID_GRID_SIZE] = "Invalid grid size",
|
||||
[QUIRC_ERROR_INVALID_VERSION] = "Invalid version",
|
||||
[QUIRC_ERROR_FORMAT_ECC] = "Format data ECC failure",
|
||||
[QUIRC_ERROR_DATA_ECC] = "ECC failure",
|
||||
[QUIRC_ERROR_UNKNOWN_DATA_TYPE] = "Unknown data type",
|
||||
[QUIRC_ERROR_DATA_OVERFLOW] = "Data overflow",
|
||||
[QUIRC_ERROR_DATA_UNDERFLOW] = "Data underflow"};
|
||||
|
||||
const char *quirc_strerror(quirc_decode_error_t err)
|
||||
{
|
||||
if (err >= 0 && err < sizeof(error_table) / sizeof(error_table[0]))
|
||||
return error_table[err];
|
||||
|
||||
return "Unknown error";
|
||||
}
|
178
ESP32QRReaderDBWriter/quirc.h
Normal file
178
ESP32QRReaderDBWriter/quirc.h
Normal file
@ -0,0 +1,178 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef QUIRC_H_
|
||||
#define QUIRC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct quirc;
|
||||
|
||||
/* Obtain the library version string. */
|
||||
const char *quirc_version(void);
|
||||
|
||||
/* Construct a new QR-code recognizer. This function will return NULL
|
||||
* if sufficient memory could not be allocated.
|
||||
*/
|
||||
struct quirc *quirc_new(void);
|
||||
|
||||
/* Destroy a QR-code recognizer. */
|
||||
void quirc_destroy(struct quirc *q);
|
||||
|
||||
/* Resize the QR-code recognizer. The size of an image must be
|
||||
* specified before codes can be analyzed.
|
||||
*
|
||||
* This function returns 0 on success, or -1 if sufficient memory could
|
||||
* not be allocated.
|
||||
*/
|
||||
int quirc_resize(struct quirc *q, int w, int h);
|
||||
|
||||
/* These functions are used to process images for QR-code recognition.
|
||||
* quirc_begin() must first be called to obtain access to a buffer into
|
||||
* which the input image should be placed. Optionally, the current
|
||||
* width and height may be returned.
|
||||
*
|
||||
* After filling the buffer, quirc_end() should be called to process
|
||||
* the image for QR-code recognition. The locations and content of each
|
||||
* code may be obtained using accessor functions described below.
|
||||
*/
|
||||
uint8_t *quirc_begin(struct quirc *q, int *w, int *h);
|
||||
void quirc_end(struct quirc *q);
|
||||
|
||||
/* This structure describes a location in the input image buffer. */
|
||||
struct quirc_point
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* This enum describes the various decoder errors which may occur. */
|
||||
typedef enum
|
||||
{
|
||||
QUIRC_SUCCESS = 0,
|
||||
QUIRC_ERROR_INVALID_GRID_SIZE,
|
||||
QUIRC_ERROR_INVALID_VERSION,
|
||||
QUIRC_ERROR_FORMAT_ECC,
|
||||
QUIRC_ERROR_DATA_ECC,
|
||||
QUIRC_ERROR_UNKNOWN_DATA_TYPE,
|
||||
QUIRC_ERROR_DATA_OVERFLOW,
|
||||
QUIRC_ERROR_DATA_UNDERFLOW
|
||||
} quirc_decode_error_t;
|
||||
|
||||
/* Return a string error message for an error code. */
|
||||
const char *quirc_strerror(quirc_decode_error_t err);
|
||||
|
||||
/* Limits on the maximum size of QR-codes and their content. */
|
||||
#define QUIRC_MAX_BITMAP 3917
|
||||
#define QUIRC_MAX_PAYLOAD 8896
|
||||
|
||||
/* QR-code ECC types. */
|
||||
#define QUIRC_ECC_LEVEL_M 0
|
||||
#define QUIRC_ECC_LEVEL_L 1
|
||||
#define QUIRC_ECC_LEVEL_H 2
|
||||
#define QUIRC_ECC_LEVEL_Q 3
|
||||
|
||||
/* QR-code data types. */
|
||||
#define QUIRC_DATA_TYPE_NUMERIC 1
|
||||
#define QUIRC_DATA_TYPE_ALPHA 2
|
||||
#define QUIRC_DATA_TYPE_BYTE 4
|
||||
#define QUIRC_DATA_TYPE_KANJI 8
|
||||
|
||||
/* Common character encodings */
|
||||
#define QUIRC_ECI_ISO_8859_1 1
|
||||
#define QUIRC_ECI_IBM437 2
|
||||
#define QUIRC_ECI_ISO_8859_2 4
|
||||
#define QUIRC_ECI_ISO_8859_3 5
|
||||
#define QUIRC_ECI_ISO_8859_4 6
|
||||
#define QUIRC_ECI_ISO_8859_5 7
|
||||
#define QUIRC_ECI_ISO_8859_6 8
|
||||
#define QUIRC_ECI_ISO_8859_7 9
|
||||
#define QUIRC_ECI_ISO_8859_8 10
|
||||
#define QUIRC_ECI_ISO_8859_9 11
|
||||
#define QUIRC_ECI_WINDOWS_874 13
|
||||
#define QUIRC_ECI_ISO_8859_13 15
|
||||
#define QUIRC_ECI_ISO_8859_15 17
|
||||
#define QUIRC_ECI_SHIFT_JIS 20
|
||||
#define QUIRC_ECI_UTF_8 26
|
||||
|
||||
/* This structure is used to return information about detected QR codes
|
||||
* in the input image.
|
||||
*/
|
||||
struct quirc_code
|
||||
{
|
||||
/* The four corners of the QR-code, from top left, clockwise */
|
||||
struct quirc_point corners[4];
|
||||
|
||||
/* The number of cells across in the QR-code. The cell bitmap
|
||||
* is a bitmask giving the actual values of cells. If the cell
|
||||
* at (x, y) is black, then the following bit is set:
|
||||
*
|
||||
* cell_bitmap[i >> 3] & (1 << (i & 7))
|
||||
*
|
||||
* where i = (y * size) + x.
|
||||
*/
|
||||
int size;
|
||||
uint8_t cell_bitmap[QUIRC_MAX_BITMAP];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* This structure holds the decoded QR-code data */
|
||||
struct quirc_data
|
||||
{
|
||||
/* Various parameters of the QR-code. These can mostly be
|
||||
* ignored if you only care about the data.
|
||||
*/
|
||||
int version;
|
||||
int ecc_level;
|
||||
int mask;
|
||||
|
||||
/* This field is the highest-valued data type found in the QR
|
||||
* code.
|
||||
*/
|
||||
int data_type;
|
||||
|
||||
/* Data payload. For the Kanji datatype, payload is encoded as
|
||||
* Shift-JIS. For all other datatypes, payload is ASCII text.
|
||||
*/
|
||||
uint8_t payload[QUIRC_MAX_PAYLOAD];
|
||||
int payload_len;
|
||||
|
||||
/* ECI assignment number */
|
||||
uint32_t eci;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* Return the number of QR-codes identified in the last processed
|
||||
* image.
|
||||
*/
|
||||
int quirc_count(const struct quirc *q);
|
||||
|
||||
/* Extract the QR-code specified by the given index. */
|
||||
void quirc_extract(const struct quirc *q, int index,
|
||||
struct quirc_code *code);
|
||||
|
||||
/* Decode a QR-code, returning the payload data. */
|
||||
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
||||
struct quirc_data *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
121
ESP32QRReaderDBWriter/quirc_internal.h
Normal file
121
ESP32QRReaderDBWriter/quirc_internal.h
Normal file
@ -0,0 +1,121 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef QUIRC_INTERNAL_H_
|
||||
#define QUIRC_INTERNAL_H_
|
||||
|
||||
#include "quirc.h"
|
||||
|
||||
#define QUIRC_PIXEL_WHITE 0
|
||||
#define QUIRC_PIXEL_BLACK 1
|
||||
#define QUIRC_PIXEL_REGION 2
|
||||
|
||||
#ifndef QUIRC_MAX_REGIONS
|
||||
#define QUIRC_MAX_REGIONS 254
|
||||
#endif
|
||||
|
||||
#define QUIRC_MAX_CAPSTONES 32
|
||||
#define QUIRC_MAX_GRIDS 8
|
||||
|
||||
#define QUIRC_PERSPECTIVE_PARAMS 8
|
||||
|
||||
#if QUIRC_MAX_REGIONS < UINT8_MAX
|
||||
typedef uint8_t quirc_pixel_t;
|
||||
#elif QUIRC_MAX_REGIONS < UINT16_MAX
|
||||
typedef uint16_t quirc_pixel_t;
|
||||
#else
|
||||
#error "QUIRC_MAX_REGIONS > 65534 is not supported"
|
||||
#endif
|
||||
|
||||
struct quirc_region
|
||||
{
|
||||
struct quirc_point seed;
|
||||
int count;
|
||||
int capstone;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_capstone
|
||||
{
|
||||
int ring;
|
||||
int stone;
|
||||
|
||||
struct quirc_point corners[4];
|
||||
struct quirc_point center;
|
||||
float c[QUIRC_PERSPECTIVE_PARAMS];
|
||||
|
||||
int qr_grid;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_grid
|
||||
{
|
||||
/* Capstone indices */
|
||||
int caps[3];
|
||||
|
||||
/* Alignment pattern region and corner */
|
||||
int align_region;
|
||||
struct quirc_point align;
|
||||
|
||||
/* Timing pattern endpoints */
|
||||
struct quirc_point tpep[3];
|
||||
int hscan;
|
||||
int vscan;
|
||||
|
||||
/* Grid size and perspective transform */
|
||||
int grid_size;
|
||||
float c[QUIRC_PERSPECTIVE_PARAMS];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc
|
||||
{
|
||||
uint8_t *image;
|
||||
quirc_pixel_t *pixels;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
int num_regions;
|
||||
struct quirc_region regions[QUIRC_MAX_REGIONS];
|
||||
|
||||
int num_capstones;
|
||||
struct quirc_capstone capstones[QUIRC_MAX_CAPSTONES];
|
||||
|
||||
int num_grids;
|
||||
struct quirc_grid grids[QUIRC_MAX_GRIDS];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/************************************************************************
|
||||
* QR-code version information database
|
||||
*/
|
||||
|
||||
#define QUIRC_MAX_VERSION 40
|
||||
#define QUIRC_MAX_ALIGNMENT 7
|
||||
|
||||
struct quirc_rs_params
|
||||
{
|
||||
uint8_t bs; /* Small block size */
|
||||
uint8_t dw; /* Small data words */
|
||||
uint8_t ns; /* Number of small blocks */
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_version_info
|
||||
{
|
||||
uint16_t data_bytes;
|
||||
uint8_t apat[QUIRC_MAX_ALIGNMENT];
|
||||
struct quirc_rs_params ecc[4];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
extern const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1];
|
||||
|
||||
#endif
|
184
ESP32QRReaderDBWriter/version_db.c
Normal file
184
ESP32QRReaderDBWriter/version_db.c
Normal file
@ -0,0 +1,184 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "quirc_internal.h"
|
||||
|
||||
const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = {
|
||||
{0},
|
||||
{/* Version 1 */
|
||||
.data_bytes = 26,
|
||||
.apat = {0},
|
||||
.ecc = {
|
||||
{.bs = 26, .dw = 16, .ns = 1},
|
||||
{.bs = 26, .dw = 19, .ns = 1},
|
||||
{.bs = 26, .dw = 9, .ns = 1},
|
||||
{.bs = 26, .dw = 13, .ns = 1}}},
|
||||
{/* Version 2 */
|
||||
.data_bytes = 44,
|
||||
.apat = {6, 18, 0},
|
||||
.ecc = {{.bs = 44, .dw = 28, .ns = 1}, {.bs = 44, .dw = 34, .ns = 1}, {.bs = 44, .dw = 16, .ns = 1}, {.bs = 44, .dw = 22, .ns = 1}}},
|
||||
{/* Version 3 */
|
||||
.data_bytes = 70,
|
||||
.apat = {6, 22, 0},
|
||||
.ecc = {{.bs = 70, .dw = 44, .ns = 1}, {.bs = 70, .dw = 55, .ns = 1}, {.bs = 35, .dw = 13, .ns = 2}, {.bs = 35, .dw = 17, .ns = 2}}},
|
||||
{/* Version 4 */
|
||||
.data_bytes = 100,
|
||||
.apat = {6, 26, 0},
|
||||
.ecc = {{.bs = 50, .dw = 32, .ns = 2}, {.bs = 100, .dw = 80, .ns = 1}, {.bs = 25, .dw = 9, .ns = 4}, {.bs = 50, .dw = 24, .ns = 2}}},
|
||||
{/* Version 5 */
|
||||
.data_bytes = 134,
|
||||
.apat = {6, 30, 0},
|
||||
.ecc = {{.bs = 67, .dw = 43, .ns = 2}, {.bs = 134, .dw = 108, .ns = 1}, {.bs = 33, .dw = 11, .ns = 2}, {.bs = 33, .dw = 15, .ns = 2}}},
|
||||
{/* Version 6 */
|
||||
.data_bytes = 172,
|
||||
.apat = {6, 34, 0},
|
||||
.ecc = {{.bs = 43, .dw = 27, .ns = 4}, {.bs = 86, .dw = 68, .ns = 2}, {.bs = 43, .dw = 15, .ns = 4}, {.bs = 43, .dw = 19, .ns = 4}}},
|
||||
{/* Version 7 */
|
||||
.data_bytes = 196,
|
||||
.apat = {6, 22, 38, 0},
|
||||
.ecc = {{.bs = 49, .dw = 31, .ns = 4}, {.bs = 98, .dw = 78, .ns = 2}, {.bs = 39, .dw = 13, .ns = 4}, {.bs = 32, .dw = 14, .ns = 2}}},
|
||||
{/* Version 8 */
|
||||
.data_bytes = 242,
|
||||
.apat = {6, 24, 42, 0},
|
||||
.ecc = {{.bs = 60, .dw = 38, .ns = 2}, {.bs = 121, .dw = 97, .ns = 2}, {.bs = 40, .dw = 14, .ns = 4}, {.bs = 40, .dw = 18, .ns = 4}}},
|
||||
{/* Version 9 */
|
||||
.data_bytes = 292,
|
||||
.apat = {6, 26, 46, 0},
|
||||
.ecc = {{.bs = 58, .dw = 36, .ns = 3}, {.bs = 146, .dw = 116, .ns = 2}, {.bs = 36, .dw = 12, .ns = 4}, {.bs = 36, .dw = 16, .ns = 4}}},
|
||||
{/* Version 10 */
|
||||
.data_bytes = 346,
|
||||
.apat = {6, 28, 50, 0},
|
||||
.ecc = {{.bs = 69, .dw = 43, .ns = 4}, {.bs = 86, .dw = 68, .ns = 2}, {.bs = 43, .dw = 15, .ns = 6}, {.bs = 43, .dw = 19, .ns = 6}}},
|
||||
{/* Version 11 */
|
||||
.data_bytes = 404,
|
||||
.apat = {6, 30, 54, 0},
|
||||
.ecc = {{.bs = 80, .dw = 50, .ns = 1}, {.bs = 101, .dw = 81, .ns = 4}, {.bs = 36, .dw = 12, .ns = 3}, {.bs = 50, .dw = 22, .ns = 4}}},
|
||||
{/* Version 12 */
|
||||
.data_bytes = 466,
|
||||
.apat = {6, 32, 58, 0},
|
||||
.ecc = {{.bs = 58, .dw = 36, .ns = 6}, {.bs = 116, .dw = 92, .ns = 2}, {.bs = 42, .dw = 14, .ns = 7}, {.bs = 46, .dw = 20, .ns = 4}}},
|
||||
{/* Version 13 */
|
||||
.data_bytes = 532,
|
||||
.apat = {6, 34, 62, 0},
|
||||
.ecc = {{.bs = 59, .dw = 37, .ns = 8}, {.bs = 133, .dw = 107, .ns = 4}, {.bs = 33, .dw = 11, .ns = 12}, {.bs = 44, .dw = 20, .ns = 8}}},
|
||||
{/* Version 14 */
|
||||
.data_bytes = 581,
|
||||
.apat = {6, 26, 46, 66, 0},
|
||||
.ecc = {{.bs = 64, .dw = 40, .ns = 4}, {.bs = 145, .dw = 115, .ns = 3}, {.bs = 36, .dw = 12, .ns = 11}, {.bs = 36, .dw = 16, .ns = 11}}},
|
||||
{/* Version 15 */
|
||||
.data_bytes = 655,
|
||||
.apat = {6, 26, 48, 70, 0},
|
||||
.ecc = {{.bs = 65, .dw = 41, .ns = 5}, {.bs = 109, .dw = 87, .ns = 5}, {.bs = 36, .dw = 12, .ns = 11}, {.bs = 54, .dw = 24, .ns = 5}}},
|
||||
{/* Version 16 */
|
||||
.data_bytes = 733,
|
||||
.apat = {6, 26, 50, 74, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 7}, {.bs = 122, .dw = 98, .ns = 5}, {.bs = 45, .dw = 15, .ns = 3}, {.bs = 43, .dw = 19, .ns = 15}}},
|
||||
{/* Version 17 */
|
||||
.data_bytes = 815,
|
||||
.apat = {6, 30, 54, 78, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 10}, {.bs = 135, .dw = 107, .ns = 1}, {.bs = 42, .dw = 14, .ns = 2}, {.bs = 50, .dw = 22, .ns = 1}}},
|
||||
{/* Version 18 */
|
||||
.data_bytes = 901,
|
||||
.apat = {6, 30, 56, 82, 0},
|
||||
.ecc = {{.bs = 69, .dw = 43, .ns = 9}, {.bs = 150, .dw = 120, .ns = 5}, {.bs = 42, .dw = 14, .ns = 2}, {.bs = 50, .dw = 22, .ns = 17}}},
|
||||
{/* Version 19 */
|
||||
.data_bytes = 991,
|
||||
.apat = {6, 30, 58, 86, 0},
|
||||
.ecc = {{.bs = 70, .dw = 44, .ns = 3}, {.bs = 141, .dw = 113, .ns = 3}, {.bs = 39, .dw = 13, .ns = 9}, {.bs = 47, .dw = 21, .ns = 17}}},
|
||||
{/* Version 20 */
|
||||
.data_bytes = 1085,
|
||||
.apat = {6, 34, 62, 90, 0},
|
||||
.ecc = {{.bs = 67, .dw = 41, .ns = 3}, {.bs = 135, .dw = 107, .ns = 3}, {.bs = 43, .dw = 15, .ns = 15}, {.bs = 54, .dw = 24, .ns = 15}}},
|
||||
{/* Version 21 */
|
||||
.data_bytes = 1156,
|
||||
.apat = {6, 28, 50, 72, 92, 0},
|
||||
.ecc = {{.bs = 68, .dw = 42, .ns = 17}, {.bs = 144, .dw = 116, .ns = 4}, {.bs = 46, .dw = 16, .ns = 19}, {.bs = 50, .dw = 22, .ns = 17}}},
|
||||
{/* Version 22 */
|
||||
.data_bytes = 1258,
|
||||
.apat = {6, 26, 50, 74, 98, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 17}, {.bs = 139, .dw = 111, .ns = 2}, {.bs = 37, .dw = 13, .ns = 34}, {.bs = 54, .dw = 24, .ns = 7}}},
|
||||
{/* Version 23 */
|
||||
.data_bytes = 1364,
|
||||
.apat = {6, 30, 54, 78, 102, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 4}, {.bs = 151, .dw = 121, .ns = 4}, {.bs = 45, .dw = 15, .ns = 16}, {.bs = 54, .dw = 24, .ns = 11}}},
|
||||
{/* Version 24 */
|
||||
.data_bytes = 1474,
|
||||
.apat = {6, 28, 54, 80, 106, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 6}, {.bs = 147, .dw = 117, .ns = 6}, {.bs = 46, .dw = 16, .ns = 30}, {.bs = 54, .dw = 24, .ns = 11}}},
|
||||
{/* Version 25 */
|
||||
.data_bytes = 1588,
|
||||
.apat = {6, 32, 58, 84, 110, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 8}, {.bs = 132, .dw = 106, .ns = 8}, {.bs = 45, .dw = 15, .ns = 22}, {.bs = 54, .dw = 24, .ns = 7}}},
|
||||
{/* Version 26 */
|
||||
.data_bytes = 1706,
|
||||
.apat = {6, 30, 58, 86, 114, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 19}, {.bs = 142, .dw = 114, .ns = 10}, {.bs = 46, .dw = 16, .ns = 33}, {.bs = 50, .dw = 22, .ns = 28}}},
|
||||
{/* Version 27 */
|
||||
.data_bytes = 1828,
|
||||
.apat = {6, 34, 62, 90, 118, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 22}, {.bs = 152, .dw = 122, .ns = 8}, {.bs = 45, .dw = 15, .ns = 12}, {.bs = 53, .dw = 23, .ns = 8}}},
|
||||
{/* Version 28 */
|
||||
.data_bytes = 1921,
|
||||
.apat = {6, 26, 50, 74, 98, 122, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 3}, {.bs = 147, .dw = 117, .ns = 3}, {.bs = 45, .dw = 15, .ns = 11}, {.bs = 54, .dw = 24, .ns = 4}}},
|
||||
{/* Version 29 */
|
||||
.data_bytes = 2051,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 21}, {.bs = 146, .dw = 116, .ns = 7}, {.bs = 45, .dw = 15, .ns = 19}, {.bs = 53, .dw = 23, .ns = 1}}},
|
||||
{/* Version 30 */
|
||||
.data_bytes = 2185,
|
||||
.apat = {6, 26, 52, 78, 104, 130, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 19}, {.bs = 145, .dw = 115, .ns = 5}, {.bs = 45, .dw = 15, .ns = 23}, {.bs = 54, .dw = 24, .ns = 15}}},
|
||||
{/* Version 31 */
|
||||
.data_bytes = 2323,
|
||||
.apat = {6, 30, 56, 82, 108, 134, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 2}, {.bs = 145, .dw = 115, .ns = 13}, {.bs = 45, .dw = 15, .ns = 23}, {.bs = 54, .dw = 24, .ns = 42}}},
|
||||
{/* Version 32 */
|
||||
.data_bytes = 2465,
|
||||
.apat = {6, 34, 60, 86, 112, 138, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 10}, {.bs = 145, .dw = 115, .ns = 17}, {.bs = 45, .dw = 15, .ns = 19}, {.bs = 54, .dw = 24, .ns = 10}}},
|
||||
{/* Version 33 */
|
||||
.data_bytes = 2611,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 14}, {.bs = 145, .dw = 115, .ns = 17}, {.bs = 45, .dw = 15, .ns = 11}, {.bs = 54, .dw = 24, .ns = 29}}},
|
||||
{/* Version 34 */
|
||||
.data_bytes = 2761,
|
||||
.apat = {6, 34, 62, 90, 118, 146, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 14}, {.bs = 145, .dw = 115, .ns = 13}, {.bs = 46, .dw = 16, .ns = 59}, {.bs = 54, .dw = 24, .ns = 44}}},
|
||||
{/* Version 35 */
|
||||
.data_bytes = 2876,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 150},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 12}, {.bs = 151, .dw = 121, .ns = 12}, {.bs = 45, .dw = 15, .ns = 22}, {.bs = 54, .dw = 24, .ns = 39}}},
|
||||
{/* Version 36 */
|
||||
.data_bytes = 3034,
|
||||
.apat = {6, 24, 50, 76, 102, 128, 154},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 6}, {.bs = 151, .dw = 121, .ns = 6}, {.bs = 45, .dw = 15, .ns = 2}, {.bs = 54, .dw = 24, .ns = 46}}},
|
||||
{/* Version 37 */
|
||||
.data_bytes = 3196,
|
||||
.apat = {6, 28, 54, 80, 106, 132, 158},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 29}, {.bs = 152, .dw = 122, .ns = 17}, {.bs = 45, .dw = 15, .ns = 24}, {.bs = 54, .dw = 24, .ns = 49}}},
|
||||
{/* Version 38 */
|
||||
.data_bytes = 3362,
|
||||
.apat = {6, 32, 58, 84, 110, 136, 162},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 13}, {.bs = 152, .dw = 122, .ns = 4}, {.bs = 45, .dw = 15, .ns = 42}, {.bs = 54, .dw = 24, .ns = 48}}},
|
||||
{/* Version 39 */
|
||||
.data_bytes = 3532,
|
||||
.apat = {6, 26, 54, 82, 110, 138, 166},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 40}, {.bs = 147, .dw = 117, .ns = 20}, {.bs = 45, .dw = 15, .ns = 10}, {.bs = 54, .dw = 24, .ns = 43}}},
|
||||
{/* Version 40 */
|
||||
.data_bytes = 3706,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 170},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 18}, {.bs = 148, .dw = 118, .ns = 19}, {.bs = 45, .dw = 15, .ns = 20}, {.bs = 54, .dw = 24, .ns = 34}}}};
|
24
ESP32QRReaderDBWriterVideoStreamer/Credentials.h
Normal file
24
ESP32QRReaderDBWriterVideoStreamer/Credentials.h
Normal file
@ -0,0 +1,24 @@
|
||||
/****************************************************************************************************************************
|
||||
Credentials.h
|
||||
Library for communicating with a MySQL or MariaDB Server
|
||||
|
||||
Based on and modified from Dr. Charles A. Bell's MySQL_Connector_Arduino Library https://github.com/ChuckBell/MySQL_Connector_Arduino
|
||||
to support nRF52, SAMD21/SAMD51, SAM DUE, STM32F/L/H/G/WB/MP1, ESP8266, ESP32, etc. boards using W5x00, ENC28J60, LAM8742A Ethernet,
|
||||
WiFiNINA, ESP-AT, built-in ESP8266/ESP32 WiFi.
|
||||
|
||||
The library provides simple and easy Client interface to MySQL or MariaDB Server.
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/MySQL_MariaDB_Generic
|
||||
Licensed under MIT license
|
||||
**********************************************************************************************************************************/
|
||||
|
||||
#ifndef Credentials_h
|
||||
#define Credentials_h
|
||||
|
||||
char ssid[] = "cpsNUCwifi"; // your network SSID (name)
|
||||
char pass[] = "ips999CPS"; // your network password
|
||||
|
||||
char user[] = "db_user"; // MySQL user login username
|
||||
char password[] = "db_password"; // MySQL user login password
|
||||
|
||||
#endif //Credentials_h
|
@ -0,0 +1,740 @@
|
||||
/*
|
||||
ESP32-CAM QR code Reader
|
||||
Author : ChungYi Fu (Kaohsiung, Taiwan) 2021-8-13 20:00
|
||||
https://www.facebook.com/francefu
|
||||
|
||||
Refer to the code
|
||||
https://github.com/alvarowolfx/ESP32QRCodeReader
|
||||
|
||||
自訂指令格式 http://192.168.xxx.xxx/control?cmd=P1;P2;P3;P4;P5;P6;P7;P8;P9
|
||||
|
||||
http://192.168.xxx.xxx/?ip //取得APIP, STAIP
|
||||
http://192.168.xxx.xxx/?mac //取得MAC位址
|
||||
http://192.168.xxx.xxx/?digitalwrite=pin;value //數位輸出
|
||||
http://192.168.xxx.xxx/?analogwrite=pin;value //類比輸出
|
||||
http://192.168.xxx.xxx/?digitalread=pin //數位讀取
|
||||
http://192.168.xxx.xxx/?analogread=pin //類比讀取
|
||||
http://192.168.xxx.xxx/?touchread=pin //觸碰讀取
|
||||
http://192.168.xxx.xxx/?restart //重啟電源
|
||||
http://192.168.xxx.xxx/?flash=value //閃光燈 value= 0~255
|
||||
http://192.168.xxx.xxx/?servo=pin;value //伺服馬達 value= 0~180
|
||||
http://192.168.xxx.xxx/?relay=pin;value //繼電器 value = 0, 1
|
||||
http://192.168.xxx.xxx/?uart=value //序列埠
|
||||
*/
|
||||
|
||||
|
||||
/*********
|
||||
Rui Santos
|
||||
Complete project details at https://RandomNerdTutorials.com/esp32-cam-video-streaming-web-server-camera-home-assistant/
|
||||
|
||||
IMPORTANT!!!
|
||||
- Select Board "AI Thinker ESP32-CAM"
|
||||
- GPIO 0 must be connected to GND to upload a sketch
|
||||
- After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
*********/
|
||||
|
||||
|
||||
|
||||
// Serial.printf(); kann anscheinend keine Strings ausgeben, die länger als 13 Zeichen sind -> dadurch gehts: Serial.printf("Insertcommand: %s\n:", INSERT_SQL.c_str());
|
||||
|
||||
#include "esp_camera.h" //視訊函式
|
||||
//#include "soc/soc.h" //用於電源不穩不重開機
|
||||
#include "soc/rtc_cntl_reg.h" //用於電源不穩不重開機
|
||||
#include "quirc.h"
|
||||
|
||||
//Includes&defines etc für den MariaDB Entry ###########################################################
|
||||
#include "defines.h"
|
||||
#include "Credentials.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <MySQL_Generic.h>
|
||||
|
||||
#define USING_HOST_NAME false
|
||||
|
||||
#if USING_HOST_NAME
|
||||
// Optional using hostname, and Ethernet built-in DNS lookup
|
||||
char server[] = "your_account.ddns.net"; // change to your server's hostname/URL
|
||||
#else
|
||||
IPAddress server(10, 42, 0, 1);
|
||||
#endif
|
||||
|
||||
uint16_t server_port = 3306; //5698;
|
||||
|
||||
char default_database[] = "myTestDb"; //"test_arduino";
|
||||
char default_table[] = "myTestTable"; //"test_arduino";
|
||||
|
||||
String default_value = "defaultString";
|
||||
|
||||
// Sample query
|
||||
String INSERT_SQL = String("INSERT INTO ") + default_database + "." + default_table
|
||||
+ " (qrCodeText) VALUES ('" + default_value + "')";
|
||||
|
||||
|
||||
#define LED_BUILTIN 4 //die Zeile wird für das LED benötigt
|
||||
|
||||
|
||||
MySQL_Connection conn((Client *)&client);
|
||||
|
||||
MySQL_Query *query_mem;
|
||||
//Includes&defines etc für den MariaDB Entry - ENDE ####################################################
|
||||
|
||||
TaskHandle_t Task;
|
||||
|
||||
//ESP32-CAM 安信可模組腳位設定
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 0
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 21
|
||||
#define Y4_GPIO_NUM 19
|
||||
#define Y3_GPIO_NUM 18
|
||||
#define Y2_GPIO_NUM 5
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
struct QRCodeData
|
||||
{
|
||||
bool valid;
|
||||
int dataType;
|
||||
uint8_t payload[1024];
|
||||
int payloadLen;
|
||||
};
|
||||
|
||||
struct quirc *q = NULL;
|
||||
uint8_t *image = NULL;
|
||||
camera_fb_t * fb = NULL;
|
||||
struct quirc_code code;
|
||||
struct quirc_data data;
|
||||
quirc_decode_error_t err;
|
||||
struct QRCodeData qrCodeData;
|
||||
String QRCodeResult = "";
|
||||
|
||||
camera_config_t config;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Videostreamer - Anfang ################################################
|
||||
#include "esp_camera.h"
|
||||
#include <WiFi.h>
|
||||
#include "esp_timer.h"
|
||||
#include "img_converters.h"
|
||||
#include "Arduino.h"
|
||||
#include "fb_gfx.h"
|
||||
#include "soc/soc.h" //disable brownout problems
|
||||
#include "soc/rtc_cntl_reg.h" //disable brownout problems
|
||||
#include "esp_http_server.h"
|
||||
|
||||
//Replace with your network credentials
|
||||
//const char* ssid = "cpsNUCwifi";
|
||||
//const char* pass = "ips999CPS";
|
||||
|
||||
#define PART_BOUNDARY "123456789000000000000987654321"
|
||||
|
||||
// This project was tested with the AI Thinker Model, M5STACK PSRAM Model and M5STACK WITHOUT PSRAM
|
||||
#define CAMERA_MODEL_AI_THINKER
|
||||
//#define CAMERA_MODEL_M5STACK_PSRAM
|
||||
//#define CAMERA_MODEL_M5STACK_WITHOUT_PSRAM
|
||||
|
||||
// Not tested with this model
|
||||
//#define CAMERA_MODEL_WROVER_KIT
|
||||
|
||||
#if defined(CAMERA_MODEL_WROVER_KIT)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 21
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 19
|
||||
#define Y4_GPIO_NUM 18
|
||||
#define Y3_GPIO_NUM 5
|
||||
#define Y2_GPIO_NUM 4
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_WITHOUT_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 17
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_AI_THINKER)
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 0
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 21
|
||||
#define Y4_GPIO_NUM 19
|
||||
#define Y3_GPIO_NUM 18
|
||||
#define Y2_GPIO_NUM 5
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
#else
|
||||
#error "Camera model not selected"
|
||||
#endif
|
||||
|
||||
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";
|
||||
|
||||
httpd_handle_t stream_httpd = NULL;
|
||||
|
||||
static esp_err_t stream_handler(httpd_req_t *req){ //wenn via Browser (ip-Adresseingabe) auf den Stream zugegriffen wird, dann wird die Methode aufgerufen
|
||||
camera_fb_t * fb = NULL;
|
||||
esp_err_t res = ESP_OK;
|
||||
size_t _jpg_buf_len = 0;
|
||||
uint8_t * _jpg_buf = NULL;
|
||||
char * part_buf[64];
|
||||
|
||||
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
|
||||
if(res != ESP_OK){
|
||||
return res;
|
||||
}
|
||||
|
||||
while(true){
|
||||
fb = esp_camera_fb_get();
|
||||
if (!fb) {
|
||||
Serial.println("Camera capture failed");
|
||||
res = ESP_FAIL;
|
||||
} else {
|
||||
if(fb->width > 400){
|
||||
if(fb->format != PIXFORMAT_JPEG){
|
||||
bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
|
||||
esp_camera_fb_return(fb);
|
||||
fb = NULL;
|
||||
if(!jpeg_converted){
|
||||
Serial.println("JPEG compression failed");
|
||||
res = ESP_FAIL;
|
||||
}
|
||||
} else {
|
||||
_jpg_buf_len = fb->len;
|
||||
_jpg_buf = fb->buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
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(res == ESP_OK){
|
||||
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
|
||||
}
|
||||
if(fb){
|
||||
esp_camera_fb_return(fb);
|
||||
fb = NULL;
|
||||
_jpg_buf = NULL;
|
||||
} else if(_jpg_buf){
|
||||
free(_jpg_buf);
|
||||
_jpg_buf = NULL;
|
||||
}
|
||||
if(res != ESP_OK){
|
||||
break;
|
||||
}
|
||||
//Serial.printf("MJPG: %uB\n",(uint32_t)(_jpg_buf_len));
|
||||
Serial.println("Ausgabe");
|
||||
}
|
||||
Serial.println("Ausgabe dannach");
|
||||
return res;
|
||||
}
|
||||
|
||||
void startCameraServer(){
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
config.server_port = 80;
|
||||
|
||||
Serial.println("davor");
|
||||
httpd_uri_t index_uri = {
|
||||
.uri = "/",
|
||||
.method = HTTP_GET,
|
||||
.handler = stream_handler,
|
||||
.user_ctx = NULL
|
||||
};
|
||||
Serial.println("dannach");
|
||||
|
||||
//Serial.printf("Starting web server on port: '%d'\n", config.server_port);
|
||||
if (httpd_start(&stream_httpd, &config) == ESP_OK) {
|
||||
httpd_register_uri_handler(stream_httpd, &index_uri);
|
||||
}
|
||||
}
|
||||
// Videostreamer ENDE ###################################################################
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void setup() {
|
||||
|
||||
|
||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //關閉電源不穩就重開機的設定
|
||||
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true); //開啟診斷輸出
|
||||
Serial.println();
|
||||
|
||||
pinMode(LED_BUILTIN, OUTPUT); //die Zeile wird für das LED benötigt
|
||||
|
||||
|
||||
|
||||
|
||||
//Setup für insert in MariaDB #########################################################
|
||||
|
||||
while (!Serial && millis() < 5000); // wait for serial port to connect
|
||||
|
||||
MYSQL_DISPLAY1("\nStarting Basic_Insert_WiFi on", BOARD_NAME);
|
||||
MYSQL_DISPLAY(MYSQL_MARIADB_GENERIC_VERSION);
|
||||
|
||||
// Remember to initialize your WiFi module
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#if ( USING_WIFI_ESP8266_AT )
|
||||
MYSQL_DISPLAY("Using ESP8266_AT/ESP8266_AT_WebServer Library");
|
||||
#elif ( USING_WIFIESPAT_LIB )
|
||||
MYSQL_DISPLAY("Using WiFiEspAT Library");
|
||||
#endif
|
||||
|
||||
// initialize serial for ESP module
|
||||
EspSerial.begin(115200);
|
||||
// initialize ESP module
|
||||
WiFi.init(&EspSerial);
|
||||
|
||||
MYSQL_DISPLAY(F("WiFi shield init done"));
|
||||
|
||||
// check for the presence of the shield
|
||||
if (WiFi.status() == WL_NO_SHIELD)
|
||||
{
|
||||
MYSQL_DISPLAY(F("WiFi shield not present"));
|
||||
// don't continue
|
||||
while (true);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Begin WiFi section
|
||||
MYSQL_DISPLAY1("Connecting to", ssid);
|
||||
|
||||
WiFi.begin(ssid, pass);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
delay(500);
|
||||
MYSQL_DISPLAY0(".");
|
||||
|
||||
//ESP32-LED Output, dass es nicht mit dem WLAN verbunden ist
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// print out info about the connection:
|
||||
MYSQL_DISPLAY1("Connected to network. My IP address is:", WiFi.localIP());
|
||||
|
||||
MYSQL_DISPLAY3("Connecting to SQL Server @", server, ", Port =", server_port);
|
||||
MYSQL_DISPLAY5("User =", user, ", PW =", password, ", DB =", default_database);
|
||||
|
||||
|
||||
//ESP32-LED Output, dass es mit dem WLAN verbunden ist
|
||||
for(int i=0; i<3;i++){
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
delay(300);
|
||||
}
|
||||
|
||||
//Setup für insert in MariaDB - Ende #########################################################
|
||||
|
||||
|
||||
//Setup für den QR-Code Reader ###############################################################
|
||||
|
||||
config.ledc_channel = LEDC_CHANNEL_0;
|
||||
config.ledc_timer = LEDC_TIMER_0;
|
||||
config.pin_d0 = Y2_GPIO_NUM;
|
||||
config.pin_d1 = Y3_GPIO_NUM;
|
||||
config.pin_d2 = Y4_GPIO_NUM;
|
||||
config.pin_d3 = Y5_GPIO_NUM;
|
||||
config.pin_d4 = Y6_GPIO_NUM;
|
||||
config.pin_d5 = Y7_GPIO_NUM;
|
||||
config.pin_d6 = Y8_GPIO_NUM;
|
||||
config.pin_d7 = Y9_GPIO_NUM;
|
||||
config.pin_xclk = XCLK_GPIO_NUM;
|
||||
config.pin_pclk = PCLK_GPIO_NUM;
|
||||
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||
config.pin_href = HREF_GPIO_NUM;
|
||||
config.pin_sscb_sda = SIOD_GPIO_NUM;
|
||||
config.pin_sscb_scl = SIOC_GPIO_NUM;
|
||||
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||
config.pin_reset = RESET_GPIO_NUM;
|
||||
config.xclk_freq_hz = 10000000; // beim QR Reader sind es 10000000
|
||||
//config.pixel_format = PIXFORMAT_JPEG; // PIXFORMAT_GRAYSCALE
|
||||
config.pixel_format = PIXFORMAT_GRAYSCALE; // PIXFORMAT_GRAYSCALE
|
||||
|
||||
config.frame_size = FRAMESIZE_QVGA;
|
||||
config.jpeg_quality = 15;
|
||||
config.fb_count = 1;
|
||||
/*
|
||||
if(psramFound()){
|
||||
config.frame_size = FRAMESIZE_SVGA; //
|
||||
//config.frame_size = FRAMESIZE_UXGA; // das UXGA Format wirft in Kombination mit anderen Configs errors - FRAMESIZE_QVGA
|
||||
config.jpeg_quality = 10; //15
|
||||
config.fb_count = 2; //1
|
||||
//1
|
||||
} else {
|
||||
config.frame_size = FRAMESIZE_SVGA;
|
||||
config.jpeg_quality = 12;
|
||||
config.fb_count = 1;
|
||||
}
|
||||
*/
|
||||
|
||||
// Camera init
|
||||
esp_err_t err = esp_camera_init(&config); // wenn der QR-Setup auskommentiert wird, dann muss das einkommentiert werden
|
||||
if (err != ESP_OK) {
|
||||
Serial.printf("Camera init failed with error 0x%x", err);
|
||||
return;
|
||||
}
|
||||
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
s->set_framesize(s, FRAMESIZE_VGA); //der FRAMESIZE_QVGA Parameter wurde auf FRAMESIZE_SVGA geändert
|
||||
|
||||
//s->set_vflip(s, 1); //垂直翻轉
|
||||
//s->set_hmirror(s, 1); //水平鏡像
|
||||
|
||||
//閃光燈(GPIO4)
|
||||
//ledcAttachPin(4, 4);
|
||||
//ledcSetup(4, 5000, 8);
|
||||
|
||||
|
||||
|
||||
xTaskCreatePinnedToCore(
|
||||
QRCodeReader, //Task function.
|
||||
"Task", // name of task.
|
||||
10000, // Stack size of task
|
||||
NULL, // parameter of the task
|
||||
1, // priority of the task
|
||||
&Task, // Task handle to keep track of created task
|
||||
0); // pin task to core 0
|
||||
|
||||
Serial.print("listenConnection running on core ");
|
||||
Serial.println(xPortGetCoreID());
|
||||
/* */
|
||||
|
||||
//Setup für den QR-Code Reader ENDE ###############################################################
|
||||
|
||||
|
||||
|
||||
//Videostreamer Setup Anfang ########################################################################
|
||||
//WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
|
||||
|
||||
//Serial.begin(115200);
|
||||
//Serial.setDebugOutput(false);
|
||||
|
||||
//Die Konfig wurde in den QR-Code Readerteil kopiert
|
||||
/*
|
||||
//camera_config_t config;
|
||||
config.ledc_channel = LEDC_CHANNEL_0;
|
||||
config.ledc_timer = LEDC_TIMER_0;
|
||||
config.pin_d0 = Y2_GPIO_NUM;
|
||||
config.pin_d1 = Y3_GPIO_NUM;
|
||||
config.pin_d2 = Y4_GPIO_NUM;
|
||||
config.pin_d3 = Y5_GPIO_NUM;
|
||||
config.pin_d4 = Y6_GPIO_NUM;
|
||||
config.pin_d5 = Y7_GPIO_NUM;
|
||||
config.pin_d6 = Y8_GPIO_NUM;
|
||||
config.pin_d7 = Y9_GPIO_NUM;
|
||||
config.pin_xclk = XCLK_GPIO_NUM;
|
||||
config.pin_pclk = PCLK_GPIO_NUM;
|
||||
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||
config.pin_href = HREF_GPIO_NUM;
|
||||
config.pin_sscb_sda = SIOD_GPIO_NUM;
|
||||
config.pin_sscb_scl = SIOC_GPIO_NUM;
|
||||
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||
config.pin_reset = RESET_GPIO_NUM;
|
||||
config.xclk_freq_hz = 20000000; // beim QR Reader sind es 10000000
|
||||
//config.pixel_format = PIXFORMAT_JPEG; // PIXFORMAT_GRAYSCALE
|
||||
config.pixel_format = PIXFORMAT_GRAYSCALE; // PIXFORMAT_GRAYSCALE
|
||||
|
||||
|
||||
if(psramFound()){
|
||||
config.frame_size = FRAMESIZE_SVGA; //
|
||||
//config.frame_size = FRAMESIZE_UXGA; // das UXGA Format wirft in Kombination mit anderen Configs errors - FRAMESIZE_QVGA
|
||||
config.jpeg_quality = 10; //15
|
||||
config.fb_count = 2; //1
|
||||
//1
|
||||
} else {
|
||||
config.frame_size = FRAMESIZE_SVGA;
|
||||
config.jpeg_quality = 12;
|
||||
config.fb_count = 1;
|
||||
}
|
||||
|
||||
|
||||
// Camera init
|
||||
esp_err_t err = esp_camera_init(&config); // wenn der QR-Setup auskommentiert wird, dann muss das einkommentiert werden
|
||||
if (err != ESP_OK) {
|
||||
Serial.printf("Camera init failed with error 0x%x", err);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
// Wi-Fi connection
|
||||
WiFi.begin(ssid, pass);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected");
|
||||
*/
|
||||
Serial.print("Camera Stream Ready! Go to: http://");
|
||||
Serial.print(WiFi.localIP());
|
||||
|
||||
// Start streaming web server
|
||||
startCameraServer();
|
||||
//Videostreamer Setup ENDE ########################################################################
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ledOutputError(){
|
||||
|
||||
//ESP32 LED Ausgabe, dass etwas nicht funktioniert hat
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
delay(100);
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
delay(100);
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//###################################################################################
|
||||
void runInsert() // MariaDB-Insert-Funktion
|
||||
{
|
||||
// Initiate the query class instance
|
||||
MySQL_Query query_mem = MySQL_Query(&conn);
|
||||
|
||||
if (conn.connected())
|
||||
{
|
||||
MYSQL_DISPLAY(INSERT_SQL);
|
||||
|
||||
// Execute the query
|
||||
// KH, check if valid before fetching
|
||||
if ( !query_mem.execute(INSERT_SQL.c_str()) )
|
||||
{
|
||||
MYSQL_DISPLAY("Insert error");
|
||||
ledOutputError();
|
||||
}
|
||||
else
|
||||
{
|
||||
MYSQL_DISPLAY("Data Inserted.");
|
||||
|
||||
//ESP32 LED Ausgabe, dass etwas inserted wurde
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MYSQL_DISPLAY("Disconnected from Server. Can't insert.");
|
||||
ledOutputError();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void loop() {
|
||||
delay(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void charToString(const char *str, String &dbInsertString){
|
||||
|
||||
dbInsertString = ""; //max Länge 13 Zeichen für eine Ausgabe in Serial.printf
|
||||
size_t len = strlen(str);
|
||||
dbInsertString.reserve(len);
|
||||
|
||||
for(size_t i=0;i<len;i++){
|
||||
dbInsertString += str[i];
|
||||
}
|
||||
|
||||
//Serial.printf("Ausgabe des Strings: %s\n",dbInsertString.c_str());
|
||||
}
|
||||
|
||||
|
||||
//###############################################################################################----------------------------
|
||||
void QRCodeReader( void * pvParameters ){
|
||||
Serial.print("QRCodeReader running on core ");
|
||||
Serial.println(xPortGetCoreID());
|
||||
|
||||
while(1){
|
||||
Serial.println("bin in der Schleife");
|
||||
q = quirc_new();
|
||||
if (q == NULL){
|
||||
Serial.print("can't create quirc object\r\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
fb = esp_camera_fb_get();
|
||||
if (!fb)
|
||||
{
|
||||
Serial.println("Camera capture failed 2");
|
||||
continue;
|
||||
}
|
||||
|
||||
//Serial.printf("quirc_begin\r\n");
|
||||
quirc_resize(q, fb->width, fb->height);
|
||||
image = quirc_begin(q, NULL, NULL);
|
||||
//Serial.printf("Frame w h len: %d, %d, %d \r\n", fb->width, fb->height, fb->len);
|
||||
memcpy(image, fb->buf, fb->len);
|
||||
quirc_end(q);
|
||||
//Serial.printf("quirc_end\r\n");
|
||||
|
||||
int count = quirc_count(q);
|
||||
if (count > 0) {
|
||||
Serial.println(count);
|
||||
quirc_extract(q, 0, &code);
|
||||
err = quirc_decode(&code, &data);
|
||||
|
||||
if (err){
|
||||
Serial.println("Decoding FAILED");
|
||||
QRCodeResult = "Decoding FAILED";
|
||||
} else {
|
||||
Serial.printf("Decoding successful:\n");
|
||||
dumpData(&data);
|
||||
|
||||
//MariaDb-part #################--------------------
|
||||
MYSQL_DISPLAY("Connecting...");
|
||||
|
||||
//Testen des char-Array-String-Konvertierens
|
||||
//char * str = (char *) &data.payload[0];
|
||||
//charToString(str,default_value);
|
||||
|
||||
|
||||
|
||||
//Der Database-Connect (etc) Teil wirft noch errors
|
||||
|
||||
//if (conn.connect(server, server_port, user, password))
|
||||
if (conn.connectNonBlocking(server, server_port, user, password) != RESULT_FAIL)
|
||||
{
|
||||
delay(500);
|
||||
|
||||
char * str = (char *) &data.payload[0]; //nicht sicher ob man die Umwandlung braucht
|
||||
charToString(str,default_value);
|
||||
|
||||
INSERT_SQL = String("INSERT INTO ") + default_database + "." + default_table + " (qrCodeText) VALUES ('" + default_value + "')";
|
||||
//Serial.printf("Insertcommand: %s\n:", INSERT_SQL.c_str());
|
||||
|
||||
runInsert();
|
||||
conn.close(); // close the connection
|
||||
}
|
||||
else
|
||||
{
|
||||
MYSQL_DISPLAY("\nConnect failed. Trying again on next iteration.");
|
||||
ledOutputError();
|
||||
}
|
||||
|
||||
|
||||
MYSQL_DISPLAY("\nSleeping...");
|
||||
MYSQL_DISPLAY("================================================");
|
||||
delay(2000); //um nicht den gleichen Eintrag sofort doppelt drinnen zu haben
|
||||
//MariaDb-part-Ende #################--------------------
|
||||
|
||||
//vTaskDelay(3000/portTICK_RATE_MS);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
esp_camera_fb_return(fb);
|
||||
fb = NULL;
|
||||
image = NULL;
|
||||
quirc_destroy(q);
|
||||
}
|
||||
}
|
||||
|
||||
//###############################################################################################
|
||||
void dumpData(const struct quirc_data *data)
|
||||
{
|
||||
Serial.printf("Version: %d\n", data->version);
|
||||
Serial.printf("ECC level: %c\n", "MLHQ"[data->ecc_level]);
|
||||
Serial.printf("Mask: %d\n", data->mask);
|
||||
Serial.printf("Length: %d\n", data->payload_len);
|
||||
Serial.printf("Payload: %s\n", data->payload);
|
||||
|
||||
//QRCodeResult = const_cast<char*>(reinterpret_cast<const char*>(data->payload));
|
||||
|
||||
//default_value = reinterpret_cast<char*>(data.payload);
|
||||
//Serial.printf("MyTestPayload: %s\n", QRCodeResult);
|
||||
//Serial.printf("MyTestPayload: %s\n", "testString");
|
||||
|
||||
}
|
16
ESP32QRReaderDBWriterVideoStreamer/LICENSE
Normal file
16
ESP32QRReaderDBWriterVideoStreamer/LICENSE
Normal file
@ -0,0 +1,16 @@
|
||||
quirc -- QR-code recognition library
|
||||
Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all
|
||||
copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
193
ESP32QRReaderDBWriterVideoStreamer/README.md
Normal file
193
ESP32QRReaderDBWriterVideoStreamer/README.md
Normal file
@ -0,0 +1,193 @@
|
||||
Quirc
|
||||
=====
|
||||
|
||||
QR codes are a type of high-density matrix barcodes, and quirc is a library for
|
||||
extracting and decoding them from images. It has several features which make it
|
||||
a good choice for this purpose:
|
||||
|
||||
* It is fast enough to be used with realtime video: extracting and decoding
|
||||
from VGA frame takes about 50 ms on a modern x86 core.
|
||||
|
||||
* It has a robust and tolerant recognition algorithm. It can correctly
|
||||
recognise and decode QR codes which are rotated and/or oblique to the camera.
|
||||
It can also distinguish and decode multiple codes within the same image.
|
||||
|
||||
* It is easy to use, with a simple API described in a single commented header
|
||||
file (see below for an overview).
|
||||
|
||||
* It is small and easily embeddable, with no dependencies other than standard C
|
||||
functions.
|
||||
|
||||
* It has a very small memory footprint: one byte per image pixel, plus a few kB
|
||||
per decoder object.
|
||||
|
||||
* It uses no global mutable state, and is safe to use in a multithreaded
|
||||
application.
|
||||
|
||||
* BSD-licensed, with almost no restrictions regarding use and/or modification.
|
||||
|
||||
The distribution comes with, in addition to the library, several test programs.
|
||||
While the core library is very portable, these programs have some additional
|
||||
dependencies. All of them require libjpeg, and two (`quirc-demo` and `inspect`)
|
||||
require SDL. The camera demos use Linux-specific APIs:
|
||||
|
||||
### quirc-demo
|
||||
|
||||
This is an real-time demo which requires a camera and a graphical display. The
|
||||
video stream is displayed on screen as it's received, and any QR codes
|
||||
recognised are highlighted in the image, with the decoded information both
|
||||
displayed on the image and printed on stdout.
|
||||
|
||||
### quirc-scanner
|
||||
|
||||
This program turns your camera into a barcode scanner. It's almost the same as
|
||||
the `demo` application, but it doesn't display the video stream, and thus
|
||||
doesn't require a graphical display.
|
||||
|
||||
### qrtest
|
||||
|
||||
This test is used to evaluate the performance of library. Given a directory
|
||||
tree containing a bunch of JPEG images, it will attempt to locate and decode QR
|
||||
codes in each image. Speed and success statistics are collected and printed on
|
||||
stdout.
|
||||
|
||||
### inspect
|
||||
|
||||
This test is used for debugging. Given a single JPEG image, it will display a
|
||||
diagram showing the internal state of the decoder as well as printing
|
||||
additional information on stdout.
|
||||
|
||||
Installation
|
||||
------------
|
||||
To build the library and associated demos/tests, type `make`. If you need to
|
||||
decode "large" image files build with `CFLAGS="-DQUIRC_MAX_REGIONS=65534" make`
|
||||
instead. Note that this will increase the memory usage, it is discouraged for
|
||||
low resource devices (i.e. embedded).
|
||||
|
||||
Type `make install` to install the library, header file and camera demos.
|
||||
|
||||
You can specify one or several of the following targets if you don't want, or
|
||||
are unable to build everything:
|
||||
|
||||
* libquirc.a
|
||||
* libquirc.so
|
||||
* qrtest
|
||||
* inspect
|
||||
* quirc-scanner
|
||||
* quirc-demo
|
||||
|
||||
Library use
|
||||
-----------
|
||||
All of the library's functionality is exposed through a single header file,
|
||||
which you should include:
|
||||
|
||||
```C
|
||||
#include <quirc.h>
|
||||
```
|
||||
|
||||
To decode images, you'll need to instantiate a `struct quirc` object, which is
|
||||
done with the `quirc_new` function. Later, when you no longer need to decode
|
||||
anything, you should release the allocated memory with `quirc_destroy`:
|
||||
|
||||
```C
|
||||
struct quirc *qr;
|
||||
|
||||
qr = quirc_new();
|
||||
if (!qr) {
|
||||
perror("Failed to allocate memory");
|
||||
abort();
|
||||
}
|
||||
|
||||
/* ... */
|
||||
|
||||
quirc_destroy(qr);
|
||||
```
|
||||
|
||||
Having obtained a decoder object, you need to set the image size that you'll be
|
||||
working with, which is done using `quirc_resize`:
|
||||
|
||||
```C
|
||||
if (quirc_resize(qr, 640, 480) < 0) {
|
||||
perror("Failed to allocate video memory");
|
||||
abort();
|
||||
}
|
||||
```
|
||||
|
||||
`quirc_resize` and `quirc_new` are the only library functions which allocate
|
||||
memory. If you plan to process a series of frames (or a video stream), you
|
||||
probably want to allocate and size a single decoder and hold onto it to process
|
||||
each frame.
|
||||
|
||||
Processing frames is done in two stages. The first stage is an
|
||||
image-recognition stage called identification, which takes a grayscale image
|
||||
and searches for QR codes. Using `quirc_begin` and `quirc_end`, you can feed a
|
||||
grayscale image directly into the buffer that `quirc` uses for image
|
||||
processing:
|
||||
|
||||
```C
|
||||
uint8_t *image;
|
||||
int w, h;
|
||||
|
||||
image = quirc_begin(qr, &w, &h);
|
||||
|
||||
/* Fill out the image buffer here.
|
||||
* image is a pointer to a w*h bytes.
|
||||
* One byte per pixel, w pixels per line, h lines in the buffer.
|
||||
*/
|
||||
|
||||
quirc_end(qr);
|
||||
```
|
||||
|
||||
Note that `quirc_begin` simply returns a pointer to a previously allocated
|
||||
buffer. The buffer will contain uninitialized data. After the call to
|
||||
`quirc_end`, the decoder holds a list of detected QR codes which can be queried
|
||||
via `quirc_count` and `quirc_extract`.
|
||||
|
||||
At this point, the second stage of processing occurs -- decoding. This is done
|
||||
via the call to `quirc_decode`, which is not associated with a decoder object.
|
||||
|
||||
```C
|
||||
int num_codes;
|
||||
int i;
|
||||
|
||||
/* We've previously fed an image to the decoder via
|
||||
* quirc_begin/quirc_end.
|
||||
*/
|
||||
|
||||
num_codes = quirc_count(qr);
|
||||
for (i = 0; i < num_codes; i++) {
|
||||
struct quirc_code code;
|
||||
struct quirc_data data;
|
||||
quirc_decode_error_t err;
|
||||
|
||||
quirc_extract(qr, i, &code);
|
||||
|
||||
/* Decoding stage */
|
||||
err = quirc_decode(&code, &data);
|
||||
if (err)
|
||||
printf("DECODE FAILED: %s\n", quirc_strerror(err));
|
||||
else
|
||||
printf("Data: %s\n", data.payload);
|
||||
}
|
||||
```
|
||||
|
||||
`quirc_code` and `quirc_data` are flat structures which don't need to be
|
||||
initialized or freed after use.
|
||||
|
||||
Copyright
|
||||
---------
|
||||
Copyright (C) 2010-2012 Daniel Beer <<dlbeer@gmail.com>>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all
|
||||
copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
85
ESP32QRReaderDBWriterVideoStreamer/collections.c
Normal file
85
ESP32QRReaderDBWriterVideoStreamer/collections.c
Normal file
@ -0,0 +1,85 @@
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2017 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "collections.h"
|
||||
#define CHAR_BITS (sizeof(char) * 8)
|
||||
#define CHAR_MASK (CHAR_BITS - 1)
|
||||
#define CHAR_SHIFT IM_LOG2(CHAR_MASK)
|
||||
|
||||
//////////
|
||||
// lifo //
|
||||
//////////
|
||||
|
||||
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len)
|
||||
{
|
||||
ptr->len = 0;
|
||||
ptr->size = size;
|
||||
ptr->data_len = data_len;
|
||||
ptr->data = (char *)ps_malloc(size * data_len);
|
||||
}
|
||||
|
||||
void lifo_alloc_all(lifo_t *ptr, size_t *size, size_t data_len)
|
||||
{
|
||||
ptr->data = (char *)ps_malloc(255);
|
||||
ptr->data_len = data_len;
|
||||
ptr->size = 255 / data_len;
|
||||
ptr->len = 0;
|
||||
*size = ptr->size;
|
||||
}
|
||||
|
||||
void lifo_free(lifo_t *ptr)
|
||||
{
|
||||
if (ptr->data)
|
||||
{
|
||||
free(ptr->data);
|
||||
}
|
||||
}
|
||||
|
||||
void lifo_clear(lifo_t *ptr)
|
||||
{
|
||||
ptr->len = 0;
|
||||
}
|
||||
|
||||
size_t lifo_size(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len;
|
||||
}
|
||||
|
||||
bool lifo_is_not_empty(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len;
|
||||
}
|
||||
|
||||
bool lifo_is_not_full(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len != ptr->size;
|
||||
}
|
||||
|
||||
void lifo_enqueue(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(ptr->data + (ptr->len * ptr->data_len), data, ptr->data_len);
|
||||
|
||||
ptr->len += 1;
|
||||
}
|
||||
|
||||
void lifo_dequeue(lifo_t *ptr, void *data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
memcpy(data, ptr->data + ((ptr->len - 1) * ptr->data_len), ptr->data_len);
|
||||
}
|
||||
|
||||
ptr->len -= 1;
|
||||
}
|
||||
|
||||
void lifo_poke(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(ptr->data + (ptr->len * ptr->data_len), data, ptr->data_len);
|
||||
}
|
||||
|
||||
void lifo_peek(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(data, ptr->data + ((ptr->len - 1) * ptr->data_len), ptr->data_len);
|
||||
}
|
33
ESP32QRReaderDBWriterVideoStreamer/collections.h
Normal file
33
ESP32QRReaderDBWriterVideoStreamer/collections.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2017 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef __COLLECTIONS_H__
|
||||
#define __COLLECTIONS_H__
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
//////////
|
||||
// lifo //
|
||||
//////////
|
||||
|
||||
typedef struct lifo
|
||||
{
|
||||
size_t len, size, data_len;
|
||||
char *data;
|
||||
}
|
||||
__attribute__((aligned(8))) lifo_t;
|
||||
|
||||
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len);
|
||||
void lifo_alloc_all(lifo_t *ptr, size_t *size, size_t data_len);
|
||||
void lifo_free(lifo_t *ptr);
|
||||
void lifo_clear(lifo_t *ptr);
|
||||
size_t lifo_size(lifo_t *ptr);
|
||||
bool lifo_is_not_empty(lifo_t *ptr);
|
||||
bool lifo_is_not_full(lifo_t *ptr);
|
||||
void lifo_enqueue(lifo_t *ptr, void *data);
|
||||
void lifo_dequeue(lifo_t *ptr, void *data);
|
||||
void lifo_poke(lifo_t *ptr, void *data);
|
||||
void lifo_peek(lifo_t *ptr, void *data);
|
||||
|
||||
#endif /* __COLLECTIONS_H__ */
|
983
ESP32QRReaderDBWriterVideoStreamer/decode.c
Normal file
983
ESP32QRReaderDBWriterVideoStreamer/decode.c
Normal file
@ -0,0 +1,983 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "quirc_internal.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_POLY 64
|
||||
|
||||
/************************************************************************
|
||||
* Galois fields
|
||||
*/
|
||||
|
||||
struct galois_field
|
||||
{
|
||||
int p;
|
||||
const uint8_t *log;
|
||||
const uint8_t *exp;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
static const uint8_t gf16_exp[16] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x03, 0x06, 0x0c, 0x0b,
|
||||
0x05, 0x0a, 0x07, 0x0e, 0x0f, 0x0d, 0x09, 0x01};
|
||||
|
||||
static const uint8_t gf16_log[16] = {
|
||||
0x00, 0x0f, 0x01, 0x04, 0x02, 0x08, 0x05, 0x0a,
|
||||
0x03, 0x0e, 0x09, 0x07, 0x06, 0x0d, 0x0b, 0x0c};
|
||||
|
||||
static const struct galois_field gf16 = {
|
||||
.p = 15,
|
||||
.log = gf16_log,
|
||||
.exp = gf16_exp};
|
||||
|
||||
static const uint8_t gf256_exp[256] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
|
||||
0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
|
||||
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
|
||||
0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
|
||||
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
|
||||
0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
|
||||
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
|
||||
0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
|
||||
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
|
||||
0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
|
||||
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
|
||||
0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
|
||||
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
|
||||
0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
|
||||
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
|
||||
0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
|
||||
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
|
||||
0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
|
||||
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
|
||||
0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
|
||||
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
|
||||
0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
|
||||
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
|
||||
0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
|
||||
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
|
||||
0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
|
||||
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
|
||||
0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
|
||||
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
|
||||
0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
|
||||
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
|
||||
0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01};
|
||||
|
||||
static const uint8_t gf256_log[256] = {
|
||||
0x00, 0xff, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
|
||||
0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
|
||||
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
|
||||
0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
|
||||
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
|
||||
0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
|
||||
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
|
||||
0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
|
||||
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
|
||||
0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
|
||||
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
|
||||
0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
|
||||
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
|
||||
0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
|
||||
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
|
||||
0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
|
||||
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
|
||||
0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
|
||||
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
|
||||
0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
|
||||
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
|
||||
0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
|
||||
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
|
||||
0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
|
||||
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
|
||||
0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
|
||||
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
|
||||
0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
|
||||
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
|
||||
0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
|
||||
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
|
||||
0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf};
|
||||
|
||||
const static struct galois_field gf256 = {
|
||||
.p = 255,
|
||||
.log = gf256_log,
|
||||
.exp = gf256_exp};
|
||||
|
||||
/************************************************************************
|
||||
* Polynomial operations
|
||||
*/
|
||||
|
||||
static void poly_add(uint8_t *dst, const uint8_t *src, uint8_t c,
|
||||
int shift, const struct galois_field *gf)
|
||||
{
|
||||
int i;
|
||||
int log_c = gf->log[c];
|
||||
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_POLY; i++)
|
||||
{
|
||||
int p = i + shift;
|
||||
uint8_t v = src[i];
|
||||
|
||||
if (p < 0 || p >= MAX_POLY)
|
||||
continue;
|
||||
if (!v)
|
||||
continue;
|
||||
|
||||
dst[p] ^= gf->exp[(gf->log[v] + log_c) % gf->p];
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t poly_eval(const uint8_t *s, uint8_t x,
|
||||
const struct galois_field *gf)
|
||||
{
|
||||
int i;
|
||||
uint8_t sum = 0;
|
||||
uint8_t log_x = gf->log[x];
|
||||
|
||||
if (!x)
|
||||
return s[0];
|
||||
|
||||
for (i = 0; i < MAX_POLY; i++)
|
||||
{
|
||||
uint8_t c = s[i];
|
||||
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
sum ^= gf->exp[(gf->log[c] + log_x * i) % gf->p];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Berlekamp-Massey algorithm for finding error locator polynomials.
|
||||
*/
|
||||
|
||||
static void berlekamp_massey(const uint8_t *s, int N,
|
||||
const struct galois_field *gf,
|
||||
uint8_t *sigma)
|
||||
{
|
||||
uint8_t C[MAX_POLY];
|
||||
uint8_t B[MAX_POLY];
|
||||
int L = 0;
|
||||
int m = 1;
|
||||
uint8_t b = 1;
|
||||
int n;
|
||||
|
||||
memset(B, 0, sizeof(B));
|
||||
memset(C, 0, sizeof(C));
|
||||
B[0] = 1;
|
||||
C[0] = 1;
|
||||
|
||||
for (n = 0; n < N; n++)
|
||||
{
|
||||
uint8_t d = s[n];
|
||||
uint8_t mult;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= L; i++)
|
||||
{
|
||||
if (!(C[i] && s[n - i]))
|
||||
continue;
|
||||
|
||||
d ^= gf->exp[(gf->log[C[i]] +
|
||||
gf->log[s[n - i]]) %
|
||||
gf->p];
|
||||
}
|
||||
|
||||
mult = gf->exp[(gf->p - gf->log[b] + gf->log[d]) % gf->p];
|
||||
|
||||
if (!d)
|
||||
{
|
||||
m++;
|
||||
}
|
||||
else if (L * 2 <= n)
|
||||
{
|
||||
uint8_t T[MAX_POLY];
|
||||
|
||||
memcpy(T, C, sizeof(T));
|
||||
poly_add(C, B, mult, m, gf);
|
||||
memcpy(B, T, sizeof(B));
|
||||
L = n + 1 - L;
|
||||
b = d;
|
||||
m = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
poly_add(C, B, mult, m, gf);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(sigma, C, MAX_POLY);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Code stream error correction
|
||||
*
|
||||
* Generator polynomial for GF(2^8) is x^8 + x^4 + x^3 + x^2 + 1
|
||||
*/
|
||||
|
||||
static int block_syndromes(const uint8_t *data, int bs, int npar, uint8_t *s)
|
||||
{
|
||||
int nonzero = 0;
|
||||
int i;
|
||||
|
||||
memset(s, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < npar; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < bs; j++)
|
||||
{
|
||||
uint8_t c = data[bs - j - 1];
|
||||
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
s[i] ^= gf256_exp[((int)gf256_log[c] +
|
||||
i * j) %
|
||||
255];
|
||||
}
|
||||
|
||||
if (s[i])
|
||||
nonzero = 1;
|
||||
}
|
||||
|
||||
return nonzero;
|
||||
}
|
||||
|
||||
static void eloc_poly(uint8_t *omega,
|
||||
const uint8_t *s, const uint8_t *sigma,
|
||||
int npar)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(omega, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < npar; i++)
|
||||
{
|
||||
const uint8_t a = sigma[i];
|
||||
const uint8_t log_a = gf256_log[a];
|
||||
int j;
|
||||
|
||||
if (!a)
|
||||
continue;
|
||||
|
||||
for (j = 0; j + 1 < MAX_POLY; j++)
|
||||
{
|
||||
const uint8_t b = s[j + 1];
|
||||
|
||||
if (i + j >= npar)
|
||||
break;
|
||||
|
||||
if (!b)
|
||||
continue;
|
||||
|
||||
omega[i + j] ^=
|
||||
gf256_exp[(log_a + gf256_log[b]) % 255];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static quirc_decode_error_t correct_block(uint8_t *data,
|
||||
const struct quirc_rs_params *ecc)
|
||||
{
|
||||
int npar = ecc->bs - ecc->dw;
|
||||
uint8_t s[MAX_POLY];
|
||||
uint8_t sigma[MAX_POLY];
|
||||
uint8_t sigma_deriv[MAX_POLY];
|
||||
uint8_t omega[MAX_POLY];
|
||||
int i;
|
||||
|
||||
/* Compute syndrome vector */
|
||||
if (!block_syndromes(data, ecc->bs, npar, s))
|
||||
return QUIRC_SUCCESS;
|
||||
|
||||
berlekamp_massey(s, npar, &gf256, sigma);
|
||||
|
||||
/* Compute derivative of sigma */
|
||||
memset(sigma_deriv, 0, MAX_POLY);
|
||||
for (i = 0; i + 1 < MAX_POLY; i += 2)
|
||||
sigma_deriv[i] = sigma[i + 1];
|
||||
|
||||
/* Compute error evaluator polynomial */
|
||||
eloc_poly(omega, s, sigma, npar - 1);
|
||||
|
||||
/* Find error locations and magnitudes */
|
||||
for (i = 0; i < ecc->bs; i++)
|
||||
{
|
||||
uint8_t xinv = gf256_exp[255 - i];
|
||||
|
||||
if (!poly_eval(sigma, xinv, &gf256))
|
||||
{
|
||||
uint8_t sd_x = poly_eval(sigma_deriv, xinv, &gf256);
|
||||
uint8_t omega_x = poly_eval(omega, xinv, &gf256);
|
||||
uint8_t error = gf256_exp[(255 - gf256_log[sd_x] +
|
||||
gf256_log[omega_x]) %
|
||||
255];
|
||||
|
||||
data[ecc->bs - i - 1] ^= error;
|
||||
}
|
||||
}
|
||||
|
||||
if (block_syndromes(data, ecc->bs, npar, s))
|
||||
return QUIRC_ERROR_DATA_ECC;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Format value error correction
|
||||
*
|
||||
* Generator polynomial for GF(2^4) is x^4 + x + 1
|
||||
*/
|
||||
|
||||
#define FORMAT_MAX_ERROR 3
|
||||
#define FORMAT_SYNDROMES (FORMAT_MAX_ERROR * 2)
|
||||
#define FORMAT_BITS 15
|
||||
|
||||
static int format_syndromes(uint16_t u, uint8_t *s)
|
||||
{
|
||||
int i;
|
||||
int nonzero = 0;
|
||||
|
||||
memset(s, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < FORMAT_SYNDROMES; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
s[i] = 0;
|
||||
for (j = 0; j < FORMAT_BITS; j++)
|
||||
if (u & (1 << j))
|
||||
s[i] ^= gf16_exp[((i + 1) * j) % 15];
|
||||
|
||||
if (s[i])
|
||||
nonzero = 1;
|
||||
}
|
||||
|
||||
return nonzero;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t correct_format(uint16_t *f_ret)
|
||||
{
|
||||
uint16_t u = *f_ret;
|
||||
int i;
|
||||
uint8_t s[MAX_POLY];
|
||||
uint8_t sigma[MAX_POLY];
|
||||
|
||||
/* Evaluate U (received codeword) at each of alpha_1 .. alpha_6
|
||||
* to get S_1 .. S_6 (but we index them from 0).
|
||||
*/
|
||||
if (!format_syndromes(u, s))
|
||||
return QUIRC_SUCCESS;
|
||||
|
||||
berlekamp_massey(s, FORMAT_SYNDROMES, &gf16, sigma);
|
||||
|
||||
/* Now, find the roots of the polynomial */
|
||||
for (i = 0; i < 15; i++)
|
||||
if (!poly_eval(sigma, gf16_exp[15 - i], &gf16))
|
||||
u ^= (1 << i);
|
||||
|
||||
if (format_syndromes(u, s))
|
||||
return QUIRC_ERROR_FORMAT_ECC;
|
||||
|
||||
*f_ret = u;
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Decoder algorithm
|
||||
*/
|
||||
|
||||
struct datastream
|
||||
{
|
||||
uint8_t raw[QUIRC_MAX_PAYLOAD];
|
||||
int data_bits;
|
||||
int ptr;
|
||||
|
||||
uint8_t data[QUIRC_MAX_PAYLOAD];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
static inline int grid_bit(const struct quirc_code *code, int x, int y)
|
||||
{
|
||||
int p = y * code->size + x;
|
||||
|
||||
return (code->cell_bitmap[p >> 3] >> (p & 7)) & 1;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t read_format(const struct quirc_code *code,
|
||||
struct quirc_data *data, int which)
|
||||
{
|
||||
int i;
|
||||
uint16_t format = 0;
|
||||
uint16_t fdata;
|
||||
quirc_decode_error_t err;
|
||||
|
||||
if (which)
|
||||
{
|
||||
for (i = 0; i < 7; i++)
|
||||
format = (format << 1) |
|
||||
grid_bit(code, 8, code->size - 1 - i);
|
||||
for (i = 0; i < 8; i++)
|
||||
format = (format << 1) |
|
||||
grid_bit(code, code->size - 8 + i, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const int xs[15] = {
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 4, 3, 2, 1, 0};
|
||||
static const int ys[15] = {
|
||||
0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 8, 8, 8, 8, 8};
|
||||
|
||||
for (i = 14; i >= 0; i--)
|
||||
format = (format << 1) | grid_bit(code, xs[i], ys[i]);
|
||||
}
|
||||
|
||||
format ^= 0x5412;
|
||||
|
||||
err = correct_format(&format);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
fdata = format >> 10;
|
||||
data->ecc_level = fdata >> 3;
|
||||
data->mask = fdata & 7;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static int mask_bit(int mask, int i, int j)
|
||||
{
|
||||
switch (mask)
|
||||
{
|
||||
case 0:
|
||||
return !((i + j) % 2);
|
||||
case 1:
|
||||
return !(i % 2);
|
||||
case 2:
|
||||
return !(j % 3);
|
||||
case 3:
|
||||
return !((i + j) % 3);
|
||||
case 4:
|
||||
return !(((i / 2) + (j / 3)) % 2);
|
||||
case 5:
|
||||
return !((i * j) % 2 + (i * j) % 3);
|
||||
case 6:
|
||||
return !(((i * j) % 2 + (i * j) % 3) % 2);
|
||||
case 7:
|
||||
return !(((i * j) % 3 + (i + j) % 2) % 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reserved_cell(int version, int i, int j)
|
||||
{
|
||||
const struct quirc_version_info *ver = &quirc_version_db[version];
|
||||
int size = version * 4 + 17;
|
||||
int ai = -1, aj = -1, a;
|
||||
|
||||
/* Finder + format: top left */
|
||||
if (i < 9 && j < 9)
|
||||
return 1;
|
||||
|
||||
/* Finder + format: bottom left */
|
||||
if (i + 8 >= size && j < 9)
|
||||
return 1;
|
||||
|
||||
/* Finder + format: top right */
|
||||
if (i < 9 && j + 8 >= size)
|
||||
return 1;
|
||||
|
||||
/* Exclude timing patterns */
|
||||
if (i == 6 || j == 6)
|
||||
return 1;
|
||||
|
||||
/* Exclude version info, if it exists. Version info sits adjacent to
|
||||
* the top-right and bottom-left finders in three rows, bounded by
|
||||
* the timing pattern.
|
||||
*/
|
||||
if (version >= 7)
|
||||
{
|
||||
if (i < 6 && j + 11 >= size)
|
||||
return 1;
|
||||
if (i + 11 >= size && j < 6)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Exclude alignment patterns */
|
||||
for (a = 0; a < QUIRC_MAX_ALIGNMENT && ver->apat[a]; a++)
|
||||
{
|
||||
int p = ver->apat[a];
|
||||
|
||||
if (abs(p - i) < 3)
|
||||
ai = a;
|
||||
if (abs(p - j) < 3)
|
||||
aj = a;
|
||||
}
|
||||
|
||||
if (ai >= 0 && aj >= 0)
|
||||
{
|
||||
a--;
|
||||
if (ai > 0 && ai < a)
|
||||
return 1;
|
||||
if (aj > 0 && aj < a)
|
||||
return 1;
|
||||
if (aj == a && ai == a)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void read_bit(const struct quirc_code *code,
|
||||
struct quirc_data *data,
|
||||
struct datastream *ds, int i, int j)
|
||||
{
|
||||
int bitpos = ds->data_bits & 7;
|
||||
int bytepos = ds->data_bits >> 3;
|
||||
int v = grid_bit(code, j, i);
|
||||
|
||||
if (mask_bit(data->mask, i, j))
|
||||
v ^= 1;
|
||||
|
||||
if (v)
|
||||
ds->raw[bytepos] |= (0x80 >> bitpos);
|
||||
|
||||
ds->data_bits++;
|
||||
}
|
||||
|
||||
static void read_data(const struct quirc_code *code,
|
||||
struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int y = code->size - 1;
|
||||
int x = code->size - 1;
|
||||
int dir = -1;
|
||||
|
||||
while (x > 0)
|
||||
{
|
||||
if (x == 6)
|
||||
x--;
|
||||
|
||||
if (!reserved_cell(data->version, y, x))
|
||||
read_bit(code, data, ds, y, x);
|
||||
|
||||
if (!reserved_cell(data->version, y, x - 1))
|
||||
read_bit(code, data, ds, y, x - 1);
|
||||
|
||||
y += dir;
|
||||
if (y < 0 || y >= code->size)
|
||||
{
|
||||
dir = -dir;
|
||||
x -= 2;
|
||||
y += dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static quirc_decode_error_t codestream_ecc(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
const struct quirc_version_info *ver =
|
||||
&quirc_version_db[data->version];
|
||||
const struct quirc_rs_params *sb_ecc = &ver->ecc[data->ecc_level];
|
||||
struct quirc_rs_params lb_ecc;
|
||||
const int lb_count =
|
||||
(ver->data_bytes - sb_ecc->bs * sb_ecc->ns) / (sb_ecc->bs + 1);
|
||||
const int bc = lb_count + sb_ecc->ns;
|
||||
const int ecc_offset = sb_ecc->dw * bc + lb_count;
|
||||
int dst_offset = 0;
|
||||
int i;
|
||||
|
||||
memcpy(&lb_ecc, sb_ecc, sizeof(lb_ecc));
|
||||
lb_ecc.dw++;
|
||||
lb_ecc.bs++;
|
||||
|
||||
for (i = 0; i < bc; i++)
|
||||
{
|
||||
uint8_t *dst = ds->data + dst_offset;
|
||||
const struct quirc_rs_params *ecc =
|
||||
(i < sb_ecc->ns) ? sb_ecc : &lb_ecc;
|
||||
const int num_ec = ecc->bs - ecc->dw;
|
||||
quirc_decode_error_t err;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < ecc->dw; j++)
|
||||
dst[j] = ds->raw[j * bc + i];
|
||||
for (j = 0; j < num_ec; j++)
|
||||
dst[ecc->dw + j] = ds->raw[ecc_offset + j * bc + i];
|
||||
|
||||
err = correct_block(dst, ecc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dst_offset += ecc->dw;
|
||||
}
|
||||
|
||||
ds->data_bits = dst_offset * 8;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int bits_remaining(const struct datastream *ds)
|
||||
{
|
||||
return ds->data_bits - ds->ptr;
|
||||
}
|
||||
|
||||
static int take_bits(struct datastream *ds, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (len && (ds->ptr < ds->data_bits))
|
||||
{
|
||||
uint8_t b = ds->data[ds->ptr >> 3];
|
||||
int bitpos = ds->ptr & 7;
|
||||
|
||||
ret <<= 1;
|
||||
if ((b << bitpos) & 0x80)
|
||||
ret |= 1;
|
||||
|
||||
ds->ptr++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int numeric_tuple(struct quirc_data *data,
|
||||
struct datastream *ds,
|
||||
int bits, int digits)
|
||||
{
|
||||
int tuple;
|
||||
int i;
|
||||
|
||||
if (bits_remaining(ds) < bits)
|
||||
return -1;
|
||||
|
||||
tuple = take_bits(ds, bits);
|
||||
|
||||
for (i = digits - 1; i >= 0; i--)
|
||||
{
|
||||
data->payload[data->payload_len + i] = tuple % 10 + '0';
|
||||
tuple /= 10;
|
||||
}
|
||||
|
||||
data->payload_len += digits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_numeric(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 14;
|
||||
int count;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 10;
|
||||
else if (data->version < 27)
|
||||
bits = 12;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
|
||||
while (count >= 3)
|
||||
{
|
||||
if (numeric_tuple(data, ds, 10, 3) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 3;
|
||||
}
|
||||
|
||||
if (count >= 2)
|
||||
{
|
||||
if (numeric_tuple(data, ds, 7, 2) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
if (numeric_tuple(data, ds, 4, 1) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count--;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static int alpha_tuple(struct quirc_data *data,
|
||||
struct datastream *ds,
|
||||
int bits, int digits)
|
||||
{
|
||||
int tuple;
|
||||
int i;
|
||||
|
||||
if (bits_remaining(ds) < bits)
|
||||
return -1;
|
||||
|
||||
tuple = take_bits(ds, bits);
|
||||
|
||||
for (i = 0; i < digits; i++)
|
||||
{
|
||||
static const char *alpha_map =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
|
||||
|
||||
data->payload[data->payload_len + digits - i - 1] =
|
||||
alpha_map[tuple % 45];
|
||||
tuple /= 45;
|
||||
}
|
||||
|
||||
data->payload_len += digits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_alpha(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 13;
|
||||
int count;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 9;
|
||||
else if (data->version < 27)
|
||||
bits = 11;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
|
||||
while (count >= 2)
|
||||
{
|
||||
if (alpha_tuple(data, ds, 11, 2) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
if (alpha_tuple(data, ds, 6, 1) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count--;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_byte(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 16;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 8;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
if (bits_remaining(ds) < count * 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
data->payload[data->payload_len++] = take_bits(ds, 8);
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_kanji(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 12;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 8;
|
||||
else if (data->version < 27)
|
||||
bits = 10;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count * 2 + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
if (bits_remaining(ds) < count * 13)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
int d = take_bits(ds, 13);
|
||||
int msB = d / 0xc0;
|
||||
int lsB = d % 0xc0;
|
||||
int intermediate = (msB << 8) | lsB;
|
||||
uint16_t sjw;
|
||||
|
||||
if (intermediate + 0x8140 <= 0x9ffc)
|
||||
{
|
||||
/* bytes are in the range 0x8140 to 0x9FFC */
|
||||
sjw = intermediate + 0x8140;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bytes are in the range 0xE040 to 0xEBBF */
|
||||
sjw = intermediate + 0xc140;
|
||||
}
|
||||
|
||||
data->payload[data->payload_len++] = sjw >> 8;
|
||||
data->payload[data->payload_len++] = sjw & 0xff;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_eci(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
if (bits_remaining(ds) < 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = take_bits(ds, 8);
|
||||
|
||||
if ((data->eci & 0xc0) == 0x80)
|
||||
{
|
||||
if (bits_remaining(ds) < 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = (data->eci << 8) | take_bits(ds, 8);
|
||||
}
|
||||
else if ((data->eci & 0xe0) == 0xc0)
|
||||
{
|
||||
if (bits_remaining(ds) < 16)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = (data->eci << 16) | take_bits(ds, 16);
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_payload(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
while (bits_remaining(ds) >= 4)
|
||||
{
|
||||
quirc_decode_error_t err = QUIRC_SUCCESS;
|
||||
int type = take_bits(ds, 4);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case QUIRC_DATA_TYPE_NUMERIC:
|
||||
err = decode_numeric(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_ALPHA:
|
||||
err = decode_alpha(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_BYTE:
|
||||
err = decode_byte(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_KANJI:
|
||||
err = decode_kanji(data, ds);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
err = decode_eci(data, ds);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!(type & (type - 1)) && (type > data->data_type))
|
||||
data->data_type = type;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
/* Add nul terminator to all payloads */
|
||||
if (data->payload_len >= sizeof(data->payload))
|
||||
data->payload_len--;
|
||||
data->payload[data->payload_len] = 0;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
||||
struct quirc_data *data)
|
||||
{
|
||||
quirc_decode_error_t err;
|
||||
struct datastream *ds = ps_malloc(sizeof(struct datastream));
|
||||
|
||||
if ((code->size - 17) % 4)
|
||||
{
|
||||
free(ds);
|
||||
return QUIRC_ERROR_INVALID_GRID_SIZE;
|
||||
}
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
memset(ds, 0, sizeof(*ds));
|
||||
|
||||
data->version = (code->size - 17) / 4;
|
||||
|
||||
if (data->version < 1 ||
|
||||
data->version > QUIRC_MAX_VERSION)
|
||||
{
|
||||
free(ds);
|
||||
return QUIRC_ERROR_INVALID_VERSION;
|
||||
}
|
||||
|
||||
/* Read format information -- try both locations */
|
||||
err = read_format(code, data, 0);
|
||||
if (err)
|
||||
err = read_format(code, data, 1);
|
||||
if (err)
|
||||
{
|
||||
free(ds);
|
||||
return err;
|
||||
}
|
||||
|
||||
read_data(code, data, ds);
|
||||
err = codestream_ecc(data, ds);
|
||||
if (err)
|
||||
{
|
||||
free(ds);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = decode_payload(data, ds);
|
||||
if (err)
|
||||
{
|
||||
free(ds);
|
||||
return err;
|
||||
}
|
||||
|
||||
free(ds);
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
381
ESP32QRReaderDBWriterVideoStreamer/defines.h
Normal file
381
ESP32QRReaderDBWriterVideoStreamer/defines.h
Normal file
@ -0,0 +1,381 @@
|
||||
/****************************************************************************************************************************
|
||||
defines.h
|
||||
Library for communicating with a MySQL or MariaDB Server
|
||||
|
||||
Based on and modified from Dr. Charles A. Bell's MySQL_Connector_Arduino Library https://github.com/ChuckBell/MySQL_Connector_Arduino
|
||||
to support nRF52, SAMD21/SAMD51, SAM DUE, STM32F/L/H/G/WB/MP1, ESP8266, ESP32, etc. boards using W5x00, ENC28J60, LAM8742A Ethernet,
|
||||
WiFiNINA, ESP-AT, built-in ESP8266/ESP32 WiFi.
|
||||
|
||||
The library provides simple and easy Client interface to MySQL or MariaDB Server.
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/MySQL_MariaDB_Generic
|
||||
Licensed under MIT license
|
||||
**********************************************************************************************************************************/
|
||||
|
||||
#ifndef defines_h
|
||||
#define defines_h
|
||||
|
||||
#define DEBUG_ESP8266_AT_WEBSERVER_PORT Serial
|
||||
|
||||
// Debug Level from 0 to 4
|
||||
#define _ESP_AT_LOGLEVEL_ 1
|
||||
|
||||
#define MYSQL_DEBUG_PORT Serial
|
||||
|
||||
// Debug Level from 0 to 4
|
||||
#define _MYSQL_LOGLEVEL_ 1
|
||||
|
||||
#if ! (ESP8266 || ESP32 )
|
||||
// Select only one of these libraries, only for boards other than ESP8266/ESP32
|
||||
#define USING_WIFI_ESP8266_AT false
|
||||
#define USING_WIFININA_GENERIC false
|
||||
#define USING_WIFININA false
|
||||
#define USING_WIFIESPAT_LIB true
|
||||
#define USING_WIFI_CUSTOM false
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_SAMD_MKR1000)
|
||||
#if defined(USE_WIFI_NINA)
|
||||
#undef USE_WIFI_NINA
|
||||
#endif
|
||||
#define USE_WIFI_NINA false
|
||||
#define USE_WIFI101 true
|
||||
#endif
|
||||
|
||||
#if ( defined(NRF52840_FEATHER) || defined(NRF52832_FEATHER) || defined(NRF52_SERIES) || defined(ARDUINO_NRF52_ADAFRUIT) || \
|
||||
defined(NRF52840_FEATHER_SENSE) || defined(NRF52840_ITSYBITSY) || defined(NRF52840_CIRCUITPLAY) || defined(NRF52840_CLUE) || \
|
||||
defined(NRF52840_METRO) || defined(NRF52840_PCA10056) || defined(PARTICLE_XENON) || defined(NINA_B302_ublox) || defined(NINA_B112_ublox) )
|
||||
#if defined(WIFI_USE_NRF528XX)
|
||||
#undef WIFI_USE_NRF528XX
|
||||
#endif
|
||||
#define WIFI_USE_NRF528XX true
|
||||
#endif
|
||||
|
||||
#if ( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
|
||||
|| defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
|
||||
|| defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(__SAMD21G18A__) \
|
||||
|| defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD21E18A__) || defined(__SAMD51__) || defined(__SAMD51J20A__) || defined(__SAMD51J19A__) \
|
||||
|| defined(__SAMD51G19A__) || defined(__SAMD51P19A__) || defined(__SAMD21G18A__) )
|
||||
#if defined(WIFI_USE_SAMD)
|
||||
#undef WIFI_USE_SAMD
|
||||
#endif
|
||||
#define WIFI_USE_SAMD true
|
||||
#endif
|
||||
|
||||
#if ( defined(ARDUINO_SAM_DUE) || defined(__SAM3X8E__) )
|
||||
#if defined(WIFI_USE_SAM_DUE)
|
||||
#undef WIFI_USE_SAM_DUE
|
||||
#endif
|
||||
#define WIFI_USE_SAM_DUE true
|
||||
#warning Use SAM_DUE architecture
|
||||
#endif
|
||||
|
||||
#if ( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) ||defined(STM32F4) || defined(STM32F7) || \
|
||||
defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7) ||defined(STM32G0) || defined(STM32G4) || \
|
||||
defined(STM32WB) || defined(STM32MP1) )
|
||||
#if defined(WIFI_USE_STM32)
|
||||
#undef WIFI_USE_STM32
|
||||
#endif
|
||||
#define WIFI_USE_STM32 true
|
||||
#endif
|
||||
|
||||
#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_RASPBERRY_PI_PICO) || \
|
||||
defined(ARDUINO_GENERIC_RP2040) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) )
|
||||
#if defined(WIFI_USE_RP2040)
|
||||
#undef WIFI_USE_RP2040
|
||||
#endif
|
||||
#define WIFI_USE_RP2040 true
|
||||
#endif
|
||||
|
||||
#ifdef CORE_TEENSY
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
// For Teensy 4.1/4.0
|
||||
#define EspSerial Serial2 //Serial2, Pin RX2 : 7, TX2 : 8
|
||||
#endif
|
||||
|
||||
#if defined(__IMXRT1062__)
|
||||
// For Teensy 4.1/4.0
|
||||
#define BOARD_TYPE "TEENSY 4.1/4.0"
|
||||
#elif defined(__MK66FX1M0__)
|
||||
#define BOARD_TYPE "Teensy 3.6"
|
||||
#elif defined(__MK64FX512__)
|
||||
#define BOARD_TYPE "Teensy 3.5"
|
||||
#elif defined(__MKL26Z64__)
|
||||
#define BOARD_TYPE "Teensy LC"
|
||||
#elif defined(__MK20DX256__)
|
||||
#define BOARD_TYPE "Teensy 3.2" // and Teensy 3.1 (obsolete)
|
||||
#elif defined(__MK20DX128__)
|
||||
#define BOARD_TYPE "Teensy 3.0"
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
#error Teensy 2.0++ not supported yet
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#error Teensy 2.0 not supported yet
|
||||
#else
|
||||
// For Other Boards
|
||||
#define BOARD_TYPE "Unknown Teensy Board"
|
||||
#endif
|
||||
|
||||
#elif defined(WIFI_USE_NRF528XX)
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#if defined(NRF52840_FEATHER)
|
||||
#define BOARD_TYPE "NRF52840_FEATHER_EXPRESS"
|
||||
#elif defined(NRF52832_FEATHER)
|
||||
#define BOARD_TYPE "NRF52832_FEATHER"
|
||||
#elif defined(NRF52840_FEATHER_SENSE)
|
||||
#define BOARD_TYPE "NRF52840_FEATHER_SENSE"
|
||||
#elif defined(NRF52840_ITSYBITSY)
|
||||
#define BOARD_TYPE "NRF52840_ITSYBITSY_EXPRESS"
|
||||
#elif defined(NRF52840_CIRCUITPLAY)
|
||||
#define BOARD_TYPE "NRF52840_CIRCUIT_PLAYGROUND"
|
||||
#elif defined(NRF52840_CLUE)
|
||||
#define BOARD_TYPE "NRF52840_CLUE"
|
||||
#elif defined(NRF52840_METRO)
|
||||
#define BOARD_TYPE "NRF52840_METRO_EXPRESS"
|
||||
#elif defined(NRF52840_PCA10056)
|
||||
#define BOARD_TYPE "NORDIC_NRF52840DK"
|
||||
#elif defined(NINA_B302_ublox)
|
||||
#define BOARD_TYPE "NINA_B302_ublox"
|
||||
#elif defined(NINA_B112_ublox)
|
||||
#define BOARD_TYPE "NINA_B112_ublox"
|
||||
#elif defined(PARTICLE_XENON)
|
||||
#define BOARD_TYPE "PARTICLE_XENON"
|
||||
#elif defined(MDBT50Q_RX)
|
||||
#define BOARD_TYPE "RAYTAC_MDBT50Q_RX"
|
||||
#elif defined(ARDUINO_NRF52_ADAFRUIT)
|
||||
#define BOARD_TYPE "ARDUINO_NRF52_ADAFRUIT"
|
||||
#else
|
||||
#define BOARD_TYPE "nRF52 Unknown"
|
||||
#endif
|
||||
|
||||
#elif defined(WIFI_USE_SAMD)
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
// For SAMD
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_SAMD_ZERO)
|
||||
#define BOARD_TYPE "SAMD Zero"
|
||||
#elif defined(ARDUINO_SAMD_MKR1000)
|
||||
#define BOARD_TYPE "SAMD MKR1000"
|
||||
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
|
||||
#define BOARD_TYPE "SAMD MKRWIFI1010"
|
||||
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
|
||||
#define BOARD_TYPE "SAMD NANO_33_IOT"
|
||||
#elif defined(ARDUINO_SAMD_MKRFox1200)
|
||||
#define BOARD_TYPE "SAMD MKRFox1200"
|
||||
#elif ( defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) )
|
||||
#define BOARD_TYPE "SAMD MKRWAN13X0"
|
||||
#elif defined(ARDUINO_SAMD_MKRGSM1400)
|
||||
#define BOARD_TYPE "SAMD MKRGSM1400"
|
||||
#elif defined(ARDUINO_SAMD_MKRNB1500)
|
||||
#define BOARD_TYPE "SAMD MKRNB1500"
|
||||
#elif defined(ARDUINO_SAMD_MKRVIDOR4000)
|
||||
#define BOARD_TYPE "SAMD MKRVIDOR4000"
|
||||
#elif defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS"
|
||||
#elif defined(ADAFRUIT_FEATHER_M0_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_FEATHER_M0_EXPRESS"
|
||||
#elif defined(ADAFRUIT_METRO_M0_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_METRO_M0_EXPRESS"
|
||||
#elif defined(ADAFRUIT_CIRCUITPLAYGROUND_M0)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_CIRCUITPLAYGROUND_M0"
|
||||
#elif defined(ADAFRUIT_GEMMA_M0)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_GEMMA_M0"
|
||||
#elif defined(ADAFRUIT_TRINKET_M0)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_TRINKET_M0"
|
||||
#elif defined(ADAFRUIT_ITSYBITSY_M0)
|
||||
#define BOARD_TYPE "SAMD21 ADAFRUIT_ITSYBITSY_M0"
|
||||
#elif defined(ARDUINO_SAMD_HALLOWING_M0)
|
||||
#define BOARD_TYPE "SAMD21 ARDUINO_SAMD_HALLOWING_M0"
|
||||
#elif defined(ADAFRUIT_METRO_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_METRO_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_GRAND_CENTRAL_M4)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_GRAND_CENTRAL_M4"
|
||||
#elif defined(ADAFRUIT_FEATHER_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_FEATHER_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_ITSYBITSY_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_ITSYBITSY_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_TRELLIS_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_TRELLIS_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_PYPORTAL)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYPORTAL"
|
||||
#elif defined(ADAFRUIT_PYPORTAL_M4_TITANO)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYPORTAL_M4_TITANO"
|
||||
#elif defined(ADAFRUIT_PYBADGE_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYBADGE_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_METRO_M4_AIRLIFT_LITE"
|
||||
#elif defined(ADAFRUIT_PYGAMER_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYGAMER_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_PYGAMER_ADVANCE_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYGAMER_ADVANCE_M4_EXPRESS"
|
||||
#elif defined(ADAFRUIT_PYBADGE_AIRLIFT_M4)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYBADGE_AIRLIFT_M4"
|
||||
#elif defined(ADAFRUIT_MONSTER_M4SK_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_MONSTER_M4SK_EXPRESS"
|
||||
#elif defined(ADAFRUIT_HALLOWING_M4_EXPRESS)
|
||||
#define BOARD_TYPE "SAMD51 ADAFRUIT_HALLOWING_M4_EXPRESS"
|
||||
#elif defined(SEEED_WIO_TERMINAL)
|
||||
#define BOARD_TYPE "SAMD SEEED_WIO_TERMINAL"
|
||||
#elif defined(SEEED_FEMTO_M0)
|
||||
#define BOARD_TYPE "SAMD SEEED_FEMTO_M0"
|
||||
#elif defined(SEEED_XIAO_M0)
|
||||
#define BOARD_TYPE "SAMD SEEED_XIAO_M0"
|
||||
#elif defined(Wio_Lite_MG126)
|
||||
#define BOARD_TYPE "SAMD SEEED Wio_Lite_MG126"
|
||||
#elif defined(WIO_GPS_BOARD)
|
||||
#define BOARD_TYPE "SAMD SEEED WIO_GPS_BOARD"
|
||||
#elif defined(SEEEDUINO_ZERO)
|
||||
#define BOARD_TYPE "SAMD SEEEDUINO_ZERO"
|
||||
#elif defined(SEEEDUINO_LORAWAN)
|
||||
#define BOARD_TYPE "SAMD SEEEDUINO_LORAWAN"
|
||||
#elif defined(SEEED_GROVE_UI_WIRELESS)
|
||||
#define BOARD_TYPE "SAMD SEEED_GROVE_UI_WIRELESS"
|
||||
#elif defined(__SAMD21E18A__)
|
||||
#define BOARD_TYPE "SAMD21E18A"
|
||||
#elif defined(__SAMD21G18A__)
|
||||
#define BOARD_TYPE "SAMD21G18A"
|
||||
#elif defined(__SAMD51G19A__)
|
||||
#define BOARD_TYPE "SAMD51G19A"
|
||||
#elif defined(__SAMD51J19A__)
|
||||
#define BOARD_TYPE "SAMD51J19A"
|
||||
#elif defined(__SAMD51P19A__)
|
||||
#define BOARD_TYPE "__SAMD51P19A__"
|
||||
#elif defined(__SAMD51J20A__)
|
||||
#define BOARD_TYPE "SAMD51J20A"
|
||||
#elif defined(__SAM3X8E__)
|
||||
#define BOARD_TYPE "SAM3X8E"
|
||||
#elif defined(__CPU_ARC__)
|
||||
#define BOARD_TYPE "CPU_ARC"
|
||||
#elif defined(__SAMD51__)
|
||||
#define BOARD_TYPE "SAMD51"
|
||||
#else
|
||||
#define BOARD_TYPE "SAMD Unknown"
|
||||
#endif
|
||||
|
||||
#elif defined(WIFI_USE_STM32)
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
// For STM32
|
||||
#if defined(ARDUINO_NUCLEO_F767ZI)
|
||||
#warning Nucleo-144 NUCLEO_F767ZI board selected, using HardwareSerial Serial1 @ pin D0/RX and D1/TX
|
||||
// RX TX
|
||||
HardwareSerial Serial1(D0, D1);
|
||||
#elif defined(ARDUINO_NUCLEO_L053R8)
|
||||
#warning Nucleo-64 NUCLEO_L053R8 board selected, using HardwareSerial Serial1 @ pin D0/RX and D1/TX
|
||||
// RX TX
|
||||
HardwareSerial Serial1(D0, D1); // (PA3, PA2);
|
||||
#endif
|
||||
|
||||
#warning EspSerial using SERIAL_PORT_HARDWARE, can be Serial or Serial1. See your board variant.h
|
||||
#define EspSerial SERIAL_PORT_HARDWARE //Serial1
|
||||
#endif
|
||||
|
||||
#if defined(STM32F0)
|
||||
#warning STM32F0 board selected
|
||||
#define BOARD_TYPE "STM32F0"
|
||||
#elif defined(STM32F1)
|
||||
#warning STM32F1 board selected
|
||||
#define BOARD_TYPE "STM32F1"
|
||||
#elif defined(STM32F2)
|
||||
#warning STM32F2 board selected
|
||||
#define BOARD_TYPE "STM32F2"
|
||||
#elif defined(STM32F3)
|
||||
#warning STM32F3 board selected
|
||||
#define BOARD_TYPE "STM32F3"
|
||||
#elif defined(STM32F4)
|
||||
#warning STM32F4 board selected
|
||||
#define BOARD_TYPE "STM32F4"
|
||||
#elif defined(STM32F7)
|
||||
#warning STM32F7 board selected
|
||||
#define BOARD_TYPE "STM32F7"
|
||||
#elif defined(STM32L0)
|
||||
#warning STM32L0 board selected
|
||||
#define BOARD_TYPE "STM32L0"
|
||||
#elif defined(STM32L1)
|
||||
#warning STM32L1 board selected
|
||||
#define BOARD_TYPE "STM32L1"
|
||||
#elif defined(STM32L4)
|
||||
#warning STM32L4 board selected
|
||||
#define BOARD_TYPE "STM32L4"
|
||||
#elif defined(STM32H7)
|
||||
#warning STM32H7 board selected
|
||||
#define BOARD_TYPE "STM32H7"
|
||||
#elif defined(STM32G0)
|
||||
#warning STM32G0 board selected
|
||||
#define BOARD_TYPE "STM32G0"
|
||||
#elif defined(STM32G4)
|
||||
#warning STM32G4 board selected
|
||||
#define BOARD_TYPE "STM32G4"
|
||||
#elif defined(STM32WB)
|
||||
#warning STM32WB board selected
|
||||
#define BOARD_TYPE "STM32WB"
|
||||
#elif defined(STM32MP1)
|
||||
#warning STM32MP1 board selected
|
||||
#define BOARD_TYPE "STM32MP1"
|
||||
#else
|
||||
#warning STM32 unknown board selected
|
||||
#define BOARD_TYPE "STM32 Unknown"
|
||||
#endif
|
||||
|
||||
#elif (ESP8266)
|
||||
#warning ESP8266 board selected
|
||||
#define BOARD_TYPE ARDUINO_BOARD
|
||||
|
||||
#elif (ESP32)
|
||||
#warning ESP32 board selected
|
||||
#define BOARD_TYPE ARDUINO_BOARD
|
||||
|
||||
#elif defined(WIFI_USE_RP2040) && !defined(ARDUINO_ARCH_MBED)
|
||||
|
||||
// For RP2040
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#elif defined(WIFI_USE_RP2040) && defined(ARDUINO_ARCH_MBED)
|
||||
|
||||
#warning Using ARDUINO_ARCH_MBED
|
||||
|
||||
// For MBED RP2040
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_RASPBERRY_PI_PICO) || \
|
||||
defined(ARDUINO_GENERIC_RP2040) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) )
|
||||
// Only undef known BOARD_NAME to use better one
|
||||
#undef BOARD_NAME
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_RASPBERRY_PI_PICO)
|
||||
#define BOARD_NAME "MBED RASPBERRY_PI_PICO"
|
||||
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
|
||||
#define BOARD_NAME "MBED ADAFRUIT_FEATHER_RP2040"
|
||||
#elif defined(ARDUINO_GENERIC_RP2040)
|
||||
#define BOARD_NAME "MBED GENERIC_RP2040"
|
||||
#elif defined(ARDUINO_NANO_RP2040_CONNECT)
|
||||
#define BOARD_NAME "MBED NANO_RP2040_CONNECT"
|
||||
#else
|
||||
// Use default BOARD_NAME if exists
|
||||
#if !defined(BOARD_NAME)
|
||||
#define BOARD_NAME "MBED Unknown RP2040"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
// For Mega
|
||||
#if ( USING_WIFI_ESP8266_AT || USING_WIFIESPAT_LIB )
|
||||
#define EspSerial Serial1
|
||||
#endif
|
||||
|
||||
#define BOARD_TYPE "AVR Mega"
|
||||
#endif
|
||||
|
||||
#ifndef BOARD_NAME
|
||||
#define BOARD_NAME BOARD_TYPE
|
||||
#endif
|
||||
|
||||
#endif //defines_h
|
70
ESP32QRReaderDBWriterVideoStreamer/fmath.h
Normal file
70
ESP32QRReaderDBWriterVideoStreamer/fmath.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Fast approximate math functions.
|
||||
*
|
||||
*/
|
||||
#ifndef __FMATH_H
|
||||
#define __FMATH_H
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
static inline float fast_sqrtf(float x)
|
||||
{
|
||||
//return sqrtf(x);
|
||||
asm("fsqrt.s %0, %1"
|
||||
: "=f"(x)
|
||||
: "f"(x));
|
||||
return x;
|
||||
}
|
||||
static inline int fast_floorf(float x)
|
||||
{
|
||||
return (int)(x);
|
||||
}
|
||||
|
||||
static inline int fast_ceilf(float x)
|
||||
{
|
||||
return (int)(x + 0.9999f);
|
||||
}
|
||||
|
||||
static inline int fast_roundf(float x)
|
||||
{
|
||||
return (int)(x);
|
||||
}
|
||||
|
||||
static inline float fast_fabsf(float d)
|
||||
{
|
||||
return fabsf(d);
|
||||
}
|
||||
|
||||
extern int fast_floorf(float x);
|
||||
extern int fast_ceilf(float x);
|
||||
extern int fast_roundf(float x);
|
||||
extern float fast_atanf(float x);
|
||||
extern float fast_atan2f(float y, float x);
|
||||
extern float fast_expf(float x);
|
||||
extern float fast_cbrtf(float d);
|
||||
extern float fast_fabsf(float d);
|
||||
extern float fast_log(float x);
|
||||
extern float fast_log2(float x);
|
||||
extern float fast_powf(float a, float b);
|
||||
|
||||
/*#define fast_sqrtf(x) (sqrtf(x))
|
||||
#define fast_floorf(x) ((int)floorf(x))
|
||||
#define fast_ceilf(x) ((int)ceilf(x))
|
||||
#define fast_roundf(x) ((int)roundf(x))
|
||||
#define fast_atanf(x) (atanf(x))
|
||||
#define fast_atan2f(x,y) (atan2f((x),(y)))
|
||||
#define fast_expf(x) (expf(x))
|
||||
#define fast_cbrtf(x) (cbrtf(x))
|
||||
#define fast_fabsf(x) (fabsf(x))
|
||||
#define fast_log(x) (log(x))
|
||||
#define fast_log2(x) (log2(x))
|
||||
#define fast_powf(x,y) (powf((x),(y)))
|
||||
*/
|
||||
|
||||
extern const float cos_table[360];
|
||||
extern const float sin_table[360];
|
||||
#endif // __FMATH_H
|
1286
ESP32QRReaderDBWriterVideoStreamer/identify.c
Normal file
1286
ESP32QRReaderDBWriterVideoStreamer/identify.c
Normal file
File diff suppressed because it is too large
Load Diff
104
ESP32QRReaderDBWriterVideoStreamer/quirc.c
Normal file
104
ESP32QRReaderDBWriterVideoStreamer/quirc.c
Normal file
@ -0,0 +1,104 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "quirc_internal.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
const char *quirc_version(void)
|
||||
{
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
//static struct quirc _q;
|
||||
struct quirc *quirc_new(void)
|
||||
{
|
||||
struct quirc *q = ps_malloc(sizeof(*q));
|
||||
|
||||
if (!q)
|
||||
return NULL;
|
||||
|
||||
memset(q, 0, sizeof(*q));
|
||||
return q;
|
||||
}
|
||||
|
||||
void quirc_destroy(struct quirc *q)
|
||||
{
|
||||
if (q->image)
|
||||
if (q->image)
|
||||
free(q->image);
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
if (q->pixels)
|
||||
free(q->pixels);
|
||||
|
||||
if (q)
|
||||
free(q);
|
||||
}
|
||||
|
||||
//static quirc_pixel_t img_buf[320*240];
|
||||
int quirc_resize(struct quirc *q, int w, int h)
|
||||
{
|
||||
if (q->image)
|
||||
{
|
||||
free(q->image);
|
||||
}
|
||||
uint8_t *new_image = ps_malloc(w * h);
|
||||
|
||||
if (!new_image)
|
||||
return -1;
|
||||
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
{ //should gray, 1==1
|
||||
size_t new_size = w * h * sizeof(quirc_pixel_t);
|
||||
if (q->pixels)
|
||||
free(q->pixels);
|
||||
quirc_pixel_t *new_pixels = ps_malloc(new_size);
|
||||
if (!new_pixels)
|
||||
{
|
||||
free(new_image);
|
||||
return -1;
|
||||
}
|
||||
q->pixels = new_pixels;
|
||||
}
|
||||
q->image = new_image;
|
||||
q->w = w;
|
||||
q->h = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int quirc_count(const struct quirc *q)
|
||||
{
|
||||
return q->num_grids;
|
||||
}
|
||||
|
||||
static const char *const error_table[] = {
|
||||
[QUIRC_SUCCESS] = "Success",
|
||||
[QUIRC_ERROR_INVALID_GRID_SIZE] = "Invalid grid size",
|
||||
[QUIRC_ERROR_INVALID_VERSION] = "Invalid version",
|
||||
[QUIRC_ERROR_FORMAT_ECC] = "Format data ECC failure",
|
||||
[QUIRC_ERROR_DATA_ECC] = "ECC failure",
|
||||
[QUIRC_ERROR_UNKNOWN_DATA_TYPE] = "Unknown data type",
|
||||
[QUIRC_ERROR_DATA_OVERFLOW] = "Data overflow",
|
||||
[QUIRC_ERROR_DATA_UNDERFLOW] = "Data underflow"};
|
||||
|
||||
const char *quirc_strerror(quirc_decode_error_t err)
|
||||
{
|
||||
if (err >= 0 && err < sizeof(error_table) / sizeof(error_table[0]))
|
||||
return error_table[err];
|
||||
|
||||
return "Unknown error";
|
||||
}
|
178
ESP32QRReaderDBWriterVideoStreamer/quirc.h
Normal file
178
ESP32QRReaderDBWriterVideoStreamer/quirc.h
Normal file
@ -0,0 +1,178 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef QUIRC_H_
|
||||
#define QUIRC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct quirc;
|
||||
|
||||
/* Obtain the library version string. */
|
||||
const char *quirc_version(void);
|
||||
|
||||
/* Construct a new QR-code recognizer. This function will return NULL
|
||||
* if sufficient memory could not be allocated.
|
||||
*/
|
||||
struct quirc *quirc_new(void);
|
||||
|
||||
/* Destroy a QR-code recognizer. */
|
||||
void quirc_destroy(struct quirc *q);
|
||||
|
||||
/* Resize the QR-code recognizer. The size of an image must be
|
||||
* specified before codes can be analyzed.
|
||||
*
|
||||
* This function returns 0 on success, or -1 if sufficient memory could
|
||||
* not be allocated.
|
||||
*/
|
||||
int quirc_resize(struct quirc *q, int w, int h);
|
||||
|
||||
/* These functions are used to process images for QR-code recognition.
|
||||
* quirc_begin() must first be called to obtain access to a buffer into
|
||||
* which the input image should be placed. Optionally, the current
|
||||
* width and height may be returned.
|
||||
*
|
||||
* After filling the buffer, quirc_end() should be called to process
|
||||
* the image for QR-code recognition. The locations and content of each
|
||||
* code may be obtained using accessor functions described below.
|
||||
*/
|
||||
uint8_t *quirc_begin(struct quirc *q, int *w, int *h);
|
||||
void quirc_end(struct quirc *q);
|
||||
|
||||
/* This structure describes a location in the input image buffer. */
|
||||
struct quirc_point
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* This enum describes the various decoder errors which may occur. */
|
||||
typedef enum
|
||||
{
|
||||
QUIRC_SUCCESS = 0,
|
||||
QUIRC_ERROR_INVALID_GRID_SIZE,
|
||||
QUIRC_ERROR_INVALID_VERSION,
|
||||
QUIRC_ERROR_FORMAT_ECC,
|
||||
QUIRC_ERROR_DATA_ECC,
|
||||
QUIRC_ERROR_UNKNOWN_DATA_TYPE,
|
||||
QUIRC_ERROR_DATA_OVERFLOW,
|
||||
QUIRC_ERROR_DATA_UNDERFLOW
|
||||
} quirc_decode_error_t;
|
||||
|
||||
/* Return a string error message for an error code. */
|
||||
const char *quirc_strerror(quirc_decode_error_t err);
|
||||
|
||||
/* Limits on the maximum size of QR-codes and their content. */
|
||||
#define QUIRC_MAX_BITMAP 3917
|
||||
#define QUIRC_MAX_PAYLOAD 8896
|
||||
|
||||
/* QR-code ECC types. */
|
||||
#define QUIRC_ECC_LEVEL_M 0
|
||||
#define QUIRC_ECC_LEVEL_L 1
|
||||
#define QUIRC_ECC_LEVEL_H 2
|
||||
#define QUIRC_ECC_LEVEL_Q 3
|
||||
|
||||
/* QR-code data types. */
|
||||
#define QUIRC_DATA_TYPE_NUMERIC 1
|
||||
#define QUIRC_DATA_TYPE_ALPHA 2
|
||||
#define QUIRC_DATA_TYPE_BYTE 4
|
||||
#define QUIRC_DATA_TYPE_KANJI 8
|
||||
|
||||
/* Common character encodings */
|
||||
#define QUIRC_ECI_ISO_8859_1 1
|
||||
#define QUIRC_ECI_IBM437 2
|
||||
#define QUIRC_ECI_ISO_8859_2 4
|
||||
#define QUIRC_ECI_ISO_8859_3 5
|
||||
#define QUIRC_ECI_ISO_8859_4 6
|
||||
#define QUIRC_ECI_ISO_8859_5 7
|
||||
#define QUIRC_ECI_ISO_8859_6 8
|
||||
#define QUIRC_ECI_ISO_8859_7 9
|
||||
#define QUIRC_ECI_ISO_8859_8 10
|
||||
#define QUIRC_ECI_ISO_8859_9 11
|
||||
#define QUIRC_ECI_WINDOWS_874 13
|
||||
#define QUIRC_ECI_ISO_8859_13 15
|
||||
#define QUIRC_ECI_ISO_8859_15 17
|
||||
#define QUIRC_ECI_SHIFT_JIS 20
|
||||
#define QUIRC_ECI_UTF_8 26
|
||||
|
||||
/* This structure is used to return information about detected QR codes
|
||||
* in the input image.
|
||||
*/
|
||||
struct quirc_code
|
||||
{
|
||||
/* The four corners of the QR-code, from top left, clockwise */
|
||||
struct quirc_point corners[4];
|
||||
|
||||
/* The number of cells across in the QR-code. The cell bitmap
|
||||
* is a bitmask giving the actual values of cells. If the cell
|
||||
* at (x, y) is black, then the following bit is set:
|
||||
*
|
||||
* cell_bitmap[i >> 3] & (1 << (i & 7))
|
||||
*
|
||||
* where i = (y * size) + x.
|
||||
*/
|
||||
int size;
|
||||
uint8_t cell_bitmap[QUIRC_MAX_BITMAP];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* This structure holds the decoded QR-code data */
|
||||
struct quirc_data
|
||||
{
|
||||
/* Various parameters of the QR-code. These can mostly be
|
||||
* ignored if you only care about the data.
|
||||
*/
|
||||
int version;
|
||||
int ecc_level;
|
||||
int mask;
|
||||
|
||||
/* This field is the highest-valued data type found in the QR
|
||||
* code.
|
||||
*/
|
||||
int data_type;
|
||||
|
||||
/* Data payload. For the Kanji datatype, payload is encoded as
|
||||
* Shift-JIS. For all other datatypes, payload is ASCII text.
|
||||
*/
|
||||
uint8_t payload[QUIRC_MAX_PAYLOAD];
|
||||
int payload_len;
|
||||
|
||||
/* ECI assignment number */
|
||||
uint32_t eci;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* Return the number of QR-codes identified in the last processed
|
||||
* image.
|
||||
*/
|
||||
int quirc_count(const struct quirc *q);
|
||||
|
||||
/* Extract the QR-code specified by the given index. */
|
||||
void quirc_extract(const struct quirc *q, int index,
|
||||
struct quirc_code *code);
|
||||
|
||||
/* Decode a QR-code, returning the payload data. */
|
||||
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
||||
struct quirc_data *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
121
ESP32QRReaderDBWriterVideoStreamer/quirc_internal.h
Normal file
121
ESP32QRReaderDBWriterVideoStreamer/quirc_internal.h
Normal file
@ -0,0 +1,121 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef QUIRC_INTERNAL_H_
|
||||
#define QUIRC_INTERNAL_H_
|
||||
|
||||
#include "quirc.h"
|
||||
|
||||
#define QUIRC_PIXEL_WHITE 0
|
||||
#define QUIRC_PIXEL_BLACK 1
|
||||
#define QUIRC_PIXEL_REGION 2
|
||||
|
||||
#ifndef QUIRC_MAX_REGIONS
|
||||
#define QUIRC_MAX_REGIONS 254
|
||||
#endif
|
||||
|
||||
#define QUIRC_MAX_CAPSTONES 32
|
||||
#define QUIRC_MAX_GRIDS 8
|
||||
|
||||
#define QUIRC_PERSPECTIVE_PARAMS 8
|
||||
|
||||
#if QUIRC_MAX_REGIONS < UINT8_MAX
|
||||
typedef uint8_t quirc_pixel_t;
|
||||
#elif QUIRC_MAX_REGIONS < UINT16_MAX
|
||||
typedef uint16_t quirc_pixel_t;
|
||||
#else
|
||||
#error "QUIRC_MAX_REGIONS > 65534 is not supported"
|
||||
#endif
|
||||
|
||||
struct quirc_region
|
||||
{
|
||||
struct quirc_point seed;
|
||||
int count;
|
||||
int capstone;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_capstone
|
||||
{
|
||||
int ring;
|
||||
int stone;
|
||||
|
||||
struct quirc_point corners[4];
|
||||
struct quirc_point center;
|
||||
float c[QUIRC_PERSPECTIVE_PARAMS];
|
||||
|
||||
int qr_grid;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_grid
|
||||
{
|
||||
/* Capstone indices */
|
||||
int caps[3];
|
||||
|
||||
/* Alignment pattern region and corner */
|
||||
int align_region;
|
||||
struct quirc_point align;
|
||||
|
||||
/* Timing pattern endpoints */
|
||||
struct quirc_point tpep[3];
|
||||
int hscan;
|
||||
int vscan;
|
||||
|
||||
/* Grid size and perspective transform */
|
||||
int grid_size;
|
||||
float c[QUIRC_PERSPECTIVE_PARAMS];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc
|
||||
{
|
||||
uint8_t *image;
|
||||
quirc_pixel_t *pixels;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
int num_regions;
|
||||
struct quirc_region regions[QUIRC_MAX_REGIONS];
|
||||
|
||||
int num_capstones;
|
||||
struct quirc_capstone capstones[QUIRC_MAX_CAPSTONES];
|
||||
|
||||
int num_grids;
|
||||
struct quirc_grid grids[QUIRC_MAX_GRIDS];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/************************************************************************
|
||||
* QR-code version information database
|
||||
*/
|
||||
|
||||
#define QUIRC_MAX_VERSION 40
|
||||
#define QUIRC_MAX_ALIGNMENT 7
|
||||
|
||||
struct quirc_rs_params
|
||||
{
|
||||
uint8_t bs; /* Small block size */
|
||||
uint8_t dw; /* Small data words */
|
||||
uint8_t ns; /* Number of small blocks */
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_version_info
|
||||
{
|
||||
uint16_t data_bytes;
|
||||
uint8_t apat[QUIRC_MAX_ALIGNMENT];
|
||||
struct quirc_rs_params ecc[4];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
extern const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1];
|
||||
|
||||
#endif
|
184
ESP32QRReaderDBWriterVideoStreamer/version_db.c
Normal file
184
ESP32QRReaderDBWriterVideoStreamer/version_db.c
Normal file
@ -0,0 +1,184 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "quirc_internal.h"
|
||||
|
||||
const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = {
|
||||
{0},
|
||||
{/* Version 1 */
|
||||
.data_bytes = 26,
|
||||
.apat = {0},
|
||||
.ecc = {
|
||||
{.bs = 26, .dw = 16, .ns = 1},
|
||||
{.bs = 26, .dw = 19, .ns = 1},
|
||||
{.bs = 26, .dw = 9, .ns = 1},
|
||||
{.bs = 26, .dw = 13, .ns = 1}}},
|
||||
{/* Version 2 */
|
||||
.data_bytes = 44,
|
||||
.apat = {6, 18, 0},
|
||||
.ecc = {{.bs = 44, .dw = 28, .ns = 1}, {.bs = 44, .dw = 34, .ns = 1}, {.bs = 44, .dw = 16, .ns = 1}, {.bs = 44, .dw = 22, .ns = 1}}},
|
||||
{/* Version 3 */
|
||||
.data_bytes = 70,
|
||||
.apat = {6, 22, 0},
|
||||
.ecc = {{.bs = 70, .dw = 44, .ns = 1}, {.bs = 70, .dw = 55, .ns = 1}, {.bs = 35, .dw = 13, .ns = 2}, {.bs = 35, .dw = 17, .ns = 2}}},
|
||||
{/* Version 4 */
|
||||
.data_bytes = 100,
|
||||
.apat = {6, 26, 0},
|
||||
.ecc = {{.bs = 50, .dw = 32, .ns = 2}, {.bs = 100, .dw = 80, .ns = 1}, {.bs = 25, .dw = 9, .ns = 4}, {.bs = 50, .dw = 24, .ns = 2}}},
|
||||
{/* Version 5 */
|
||||
.data_bytes = 134,
|
||||
.apat = {6, 30, 0},
|
||||
.ecc = {{.bs = 67, .dw = 43, .ns = 2}, {.bs = 134, .dw = 108, .ns = 1}, {.bs = 33, .dw = 11, .ns = 2}, {.bs = 33, .dw = 15, .ns = 2}}},
|
||||
{/* Version 6 */
|
||||
.data_bytes = 172,
|
||||
.apat = {6, 34, 0},
|
||||
.ecc = {{.bs = 43, .dw = 27, .ns = 4}, {.bs = 86, .dw = 68, .ns = 2}, {.bs = 43, .dw = 15, .ns = 4}, {.bs = 43, .dw = 19, .ns = 4}}},
|
||||
{/* Version 7 */
|
||||
.data_bytes = 196,
|
||||
.apat = {6, 22, 38, 0},
|
||||
.ecc = {{.bs = 49, .dw = 31, .ns = 4}, {.bs = 98, .dw = 78, .ns = 2}, {.bs = 39, .dw = 13, .ns = 4}, {.bs = 32, .dw = 14, .ns = 2}}},
|
||||
{/* Version 8 */
|
||||
.data_bytes = 242,
|
||||
.apat = {6, 24, 42, 0},
|
||||
.ecc = {{.bs = 60, .dw = 38, .ns = 2}, {.bs = 121, .dw = 97, .ns = 2}, {.bs = 40, .dw = 14, .ns = 4}, {.bs = 40, .dw = 18, .ns = 4}}},
|
||||
{/* Version 9 */
|
||||
.data_bytes = 292,
|
||||
.apat = {6, 26, 46, 0},
|
||||
.ecc = {{.bs = 58, .dw = 36, .ns = 3}, {.bs = 146, .dw = 116, .ns = 2}, {.bs = 36, .dw = 12, .ns = 4}, {.bs = 36, .dw = 16, .ns = 4}}},
|
||||
{/* Version 10 */
|
||||
.data_bytes = 346,
|
||||
.apat = {6, 28, 50, 0},
|
||||
.ecc = {{.bs = 69, .dw = 43, .ns = 4}, {.bs = 86, .dw = 68, .ns = 2}, {.bs = 43, .dw = 15, .ns = 6}, {.bs = 43, .dw = 19, .ns = 6}}},
|
||||
{/* Version 11 */
|
||||
.data_bytes = 404,
|
||||
.apat = {6, 30, 54, 0},
|
||||
.ecc = {{.bs = 80, .dw = 50, .ns = 1}, {.bs = 101, .dw = 81, .ns = 4}, {.bs = 36, .dw = 12, .ns = 3}, {.bs = 50, .dw = 22, .ns = 4}}},
|
||||
{/* Version 12 */
|
||||
.data_bytes = 466,
|
||||
.apat = {6, 32, 58, 0},
|
||||
.ecc = {{.bs = 58, .dw = 36, .ns = 6}, {.bs = 116, .dw = 92, .ns = 2}, {.bs = 42, .dw = 14, .ns = 7}, {.bs = 46, .dw = 20, .ns = 4}}},
|
||||
{/* Version 13 */
|
||||
.data_bytes = 532,
|
||||
.apat = {6, 34, 62, 0},
|
||||
.ecc = {{.bs = 59, .dw = 37, .ns = 8}, {.bs = 133, .dw = 107, .ns = 4}, {.bs = 33, .dw = 11, .ns = 12}, {.bs = 44, .dw = 20, .ns = 8}}},
|
||||
{/* Version 14 */
|
||||
.data_bytes = 581,
|
||||
.apat = {6, 26, 46, 66, 0},
|
||||
.ecc = {{.bs = 64, .dw = 40, .ns = 4}, {.bs = 145, .dw = 115, .ns = 3}, {.bs = 36, .dw = 12, .ns = 11}, {.bs = 36, .dw = 16, .ns = 11}}},
|
||||
{/* Version 15 */
|
||||
.data_bytes = 655,
|
||||
.apat = {6, 26, 48, 70, 0},
|
||||
.ecc = {{.bs = 65, .dw = 41, .ns = 5}, {.bs = 109, .dw = 87, .ns = 5}, {.bs = 36, .dw = 12, .ns = 11}, {.bs = 54, .dw = 24, .ns = 5}}},
|
||||
{/* Version 16 */
|
||||
.data_bytes = 733,
|
||||
.apat = {6, 26, 50, 74, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 7}, {.bs = 122, .dw = 98, .ns = 5}, {.bs = 45, .dw = 15, .ns = 3}, {.bs = 43, .dw = 19, .ns = 15}}},
|
||||
{/* Version 17 */
|
||||
.data_bytes = 815,
|
||||
.apat = {6, 30, 54, 78, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 10}, {.bs = 135, .dw = 107, .ns = 1}, {.bs = 42, .dw = 14, .ns = 2}, {.bs = 50, .dw = 22, .ns = 1}}},
|
||||
{/* Version 18 */
|
||||
.data_bytes = 901,
|
||||
.apat = {6, 30, 56, 82, 0},
|
||||
.ecc = {{.bs = 69, .dw = 43, .ns = 9}, {.bs = 150, .dw = 120, .ns = 5}, {.bs = 42, .dw = 14, .ns = 2}, {.bs = 50, .dw = 22, .ns = 17}}},
|
||||
{/* Version 19 */
|
||||
.data_bytes = 991,
|
||||
.apat = {6, 30, 58, 86, 0},
|
||||
.ecc = {{.bs = 70, .dw = 44, .ns = 3}, {.bs = 141, .dw = 113, .ns = 3}, {.bs = 39, .dw = 13, .ns = 9}, {.bs = 47, .dw = 21, .ns = 17}}},
|
||||
{/* Version 20 */
|
||||
.data_bytes = 1085,
|
||||
.apat = {6, 34, 62, 90, 0},
|
||||
.ecc = {{.bs = 67, .dw = 41, .ns = 3}, {.bs = 135, .dw = 107, .ns = 3}, {.bs = 43, .dw = 15, .ns = 15}, {.bs = 54, .dw = 24, .ns = 15}}},
|
||||
{/* Version 21 */
|
||||
.data_bytes = 1156,
|
||||
.apat = {6, 28, 50, 72, 92, 0},
|
||||
.ecc = {{.bs = 68, .dw = 42, .ns = 17}, {.bs = 144, .dw = 116, .ns = 4}, {.bs = 46, .dw = 16, .ns = 19}, {.bs = 50, .dw = 22, .ns = 17}}},
|
||||
{/* Version 22 */
|
||||
.data_bytes = 1258,
|
||||
.apat = {6, 26, 50, 74, 98, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 17}, {.bs = 139, .dw = 111, .ns = 2}, {.bs = 37, .dw = 13, .ns = 34}, {.bs = 54, .dw = 24, .ns = 7}}},
|
||||
{/* Version 23 */
|
||||
.data_bytes = 1364,
|
||||
.apat = {6, 30, 54, 78, 102, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 4}, {.bs = 151, .dw = 121, .ns = 4}, {.bs = 45, .dw = 15, .ns = 16}, {.bs = 54, .dw = 24, .ns = 11}}},
|
||||
{/* Version 24 */
|
||||
.data_bytes = 1474,
|
||||
.apat = {6, 28, 54, 80, 106, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 6}, {.bs = 147, .dw = 117, .ns = 6}, {.bs = 46, .dw = 16, .ns = 30}, {.bs = 54, .dw = 24, .ns = 11}}},
|
||||
{/* Version 25 */
|
||||
.data_bytes = 1588,
|
||||
.apat = {6, 32, 58, 84, 110, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 8}, {.bs = 132, .dw = 106, .ns = 8}, {.bs = 45, .dw = 15, .ns = 22}, {.bs = 54, .dw = 24, .ns = 7}}},
|
||||
{/* Version 26 */
|
||||
.data_bytes = 1706,
|
||||
.apat = {6, 30, 58, 86, 114, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 19}, {.bs = 142, .dw = 114, .ns = 10}, {.bs = 46, .dw = 16, .ns = 33}, {.bs = 50, .dw = 22, .ns = 28}}},
|
||||
{/* Version 27 */
|
||||
.data_bytes = 1828,
|
||||
.apat = {6, 34, 62, 90, 118, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 22}, {.bs = 152, .dw = 122, .ns = 8}, {.bs = 45, .dw = 15, .ns = 12}, {.bs = 53, .dw = 23, .ns = 8}}},
|
||||
{/* Version 28 */
|
||||
.data_bytes = 1921,
|
||||
.apat = {6, 26, 50, 74, 98, 122, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 3}, {.bs = 147, .dw = 117, .ns = 3}, {.bs = 45, .dw = 15, .ns = 11}, {.bs = 54, .dw = 24, .ns = 4}}},
|
||||
{/* Version 29 */
|
||||
.data_bytes = 2051,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 21}, {.bs = 146, .dw = 116, .ns = 7}, {.bs = 45, .dw = 15, .ns = 19}, {.bs = 53, .dw = 23, .ns = 1}}},
|
||||
{/* Version 30 */
|
||||
.data_bytes = 2185,
|
||||
.apat = {6, 26, 52, 78, 104, 130, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 19}, {.bs = 145, .dw = 115, .ns = 5}, {.bs = 45, .dw = 15, .ns = 23}, {.bs = 54, .dw = 24, .ns = 15}}},
|
||||
{/* Version 31 */
|
||||
.data_bytes = 2323,
|
||||
.apat = {6, 30, 56, 82, 108, 134, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 2}, {.bs = 145, .dw = 115, .ns = 13}, {.bs = 45, .dw = 15, .ns = 23}, {.bs = 54, .dw = 24, .ns = 42}}},
|
||||
{/* Version 32 */
|
||||
.data_bytes = 2465,
|
||||
.apat = {6, 34, 60, 86, 112, 138, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 10}, {.bs = 145, .dw = 115, .ns = 17}, {.bs = 45, .dw = 15, .ns = 19}, {.bs = 54, .dw = 24, .ns = 10}}},
|
||||
{/* Version 33 */
|
||||
.data_bytes = 2611,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 14}, {.bs = 145, .dw = 115, .ns = 17}, {.bs = 45, .dw = 15, .ns = 11}, {.bs = 54, .dw = 24, .ns = 29}}},
|
||||
{/* Version 34 */
|
||||
.data_bytes = 2761,
|
||||
.apat = {6, 34, 62, 90, 118, 146, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 14}, {.bs = 145, .dw = 115, .ns = 13}, {.bs = 46, .dw = 16, .ns = 59}, {.bs = 54, .dw = 24, .ns = 44}}},
|
||||
{/* Version 35 */
|
||||
.data_bytes = 2876,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 150},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 12}, {.bs = 151, .dw = 121, .ns = 12}, {.bs = 45, .dw = 15, .ns = 22}, {.bs = 54, .dw = 24, .ns = 39}}},
|
||||
{/* Version 36 */
|
||||
.data_bytes = 3034,
|
||||
.apat = {6, 24, 50, 76, 102, 128, 154},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 6}, {.bs = 151, .dw = 121, .ns = 6}, {.bs = 45, .dw = 15, .ns = 2}, {.bs = 54, .dw = 24, .ns = 46}}},
|
||||
{/* Version 37 */
|
||||
.data_bytes = 3196,
|
||||
.apat = {6, 28, 54, 80, 106, 132, 158},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 29}, {.bs = 152, .dw = 122, .ns = 17}, {.bs = 45, .dw = 15, .ns = 24}, {.bs = 54, .dw = 24, .ns = 49}}},
|
||||
{/* Version 38 */
|
||||
.data_bytes = 3362,
|
||||
.apat = {6, 32, 58, 84, 110, 136, 162},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 13}, {.bs = 152, .dw = 122, .ns = 4}, {.bs = 45, .dw = 15, .ns = 42}, {.bs = 54, .dw = 24, .ns = 48}}},
|
||||
{/* Version 39 */
|
||||
.data_bytes = 3532,
|
||||
.apat = {6, 26, 54, 82, 110, 138, 166},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 40}, {.bs = 147, .dw = 117, .ns = 20}, {.bs = 45, .dw = 15, .ns = 10}, {.bs = 54, .dw = 24, .ns = 43}}},
|
||||
{/* Version 40 */
|
||||
.data_bytes = 3706,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 170},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 18}, {.bs = 148, .dw = 118, .ns = 19}, {.bs = 45, .dw = 15, .ns = 20}, {.bs = 54, .dw = 24, .ns = 34}}}};
|
266
ESP32_VideoStreamer/ESP32_VideoStreamer.ino
Normal file
266
ESP32_VideoStreamer/ESP32_VideoStreamer.ino
Normal file
@ -0,0 +1,266 @@
|
||||
/*********
|
||||
Rui Santos
|
||||
Complete project details at https://RandomNerdTutorials.com/esp32-cam-video-streaming-web-server-camera-home-assistant/
|
||||
|
||||
IMPORTANT!!!
|
||||
- Select Board "AI Thinker ESP32-CAM"
|
||||
- GPIO 0 must be connected to GND to upload a sketch
|
||||
- After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
*********/
|
||||
|
||||
#include "esp_camera.h"
|
||||
#include <WiFi.h>
|
||||
#include "esp_timer.h"
|
||||
#include "img_converters.h"
|
||||
#include "Arduino.h"
|
||||
#include "fb_gfx.h"
|
||||
#include "soc/soc.h" //disable brownout problems
|
||||
#include "soc/rtc_cntl_reg.h" //disable brownout problems
|
||||
#include "esp_http_server.h"
|
||||
|
||||
//Replace with your network credentials
|
||||
const char* ssid = "cpsNUCwifi";
|
||||
const char* password = "ips999CPS";
|
||||
|
||||
#define PART_BOUNDARY "123456789000000000000987654321"
|
||||
|
||||
// This project was tested with the AI Thinker Model, M5STACK PSRAM Model and M5STACK WITHOUT PSRAM
|
||||
#define CAMERA_MODEL_AI_THINKER
|
||||
//#define CAMERA_MODEL_M5STACK_PSRAM
|
||||
//#define CAMERA_MODEL_M5STACK_WITHOUT_PSRAM
|
||||
|
||||
// Not tested with this model
|
||||
//#define CAMERA_MODEL_WROVER_KIT
|
||||
|
||||
#if defined(CAMERA_MODEL_WROVER_KIT)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 21
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 19
|
||||
#define Y4_GPIO_NUM 18
|
||||
#define Y3_GPIO_NUM 5
|
||||
#define Y2_GPIO_NUM 4
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_WITHOUT_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 17
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_AI_THINKER)
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 0
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 21
|
||||
#define Y4_GPIO_NUM 19
|
||||
#define Y3_GPIO_NUM 18
|
||||
#define Y2_GPIO_NUM 5
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
#else
|
||||
#error "Camera model not selected"
|
||||
#endif
|
||||
|
||||
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";
|
||||
|
||||
httpd_handle_t stream_httpd = NULL;
|
||||
|
||||
static esp_err_t stream_handler(httpd_req_t *req){ //wenn via Browser (ip-Adresseingabe) auf den Stream zugegriffen wird, dann wird die Methode aufgerufen
|
||||
camera_fb_t * fb = NULL;
|
||||
esp_err_t res = ESP_OK;
|
||||
size_t _jpg_buf_len = 0;
|
||||
uint8_t * _jpg_buf = NULL;
|
||||
char * part_buf[64];
|
||||
|
||||
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
|
||||
if(res != ESP_OK){
|
||||
return res;
|
||||
}
|
||||
|
||||
while(true){
|
||||
fb = esp_camera_fb_get();
|
||||
if (!fb) {
|
||||
Serial.println("Camera capture failed");
|
||||
res = ESP_FAIL;
|
||||
} else {
|
||||
if(fb->width > 400){
|
||||
if(fb->format != PIXFORMAT_JPEG){
|
||||
bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
|
||||
esp_camera_fb_return(fb);
|
||||
fb = NULL;
|
||||
if(!jpeg_converted){
|
||||
Serial.println("JPEG compression failed");
|
||||
res = ESP_FAIL;
|
||||
}
|
||||
} else {
|
||||
_jpg_buf_len = fb->len;
|
||||
_jpg_buf = fb->buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
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(res == ESP_OK){
|
||||
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
|
||||
}
|
||||
if(fb){
|
||||
esp_camera_fb_return(fb);
|
||||
fb = NULL;
|
||||
_jpg_buf = NULL;
|
||||
} else if(_jpg_buf){
|
||||
free(_jpg_buf);
|
||||
_jpg_buf = NULL;
|
||||
}
|
||||
if(res != ESP_OK){
|
||||
break;
|
||||
}
|
||||
//Serial.printf("MJPG: %uB\n",(uint32_t)(_jpg_buf_len));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void startCameraServer(){
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
config.server_port = 80;
|
||||
|
||||
httpd_uri_t index_uri = {
|
||||
.uri = "/",
|
||||
.method = HTTP_GET,
|
||||
.handler = stream_handler,
|
||||
.user_ctx = NULL
|
||||
};
|
||||
|
||||
//Serial.printf("Starting web server on port: '%d'\n", config.server_port);
|
||||
if (httpd_start(&stream_httpd, &config) == ESP_OK) {
|
||||
httpd_register_uri_handler(stream_httpd, &index_uri);
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
|
||||
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(false);
|
||||
|
||||
camera_config_t config;
|
||||
config.ledc_channel = LEDC_CHANNEL_0;
|
||||
config.ledc_timer = LEDC_TIMER_0;
|
||||
config.pin_d0 = Y2_GPIO_NUM;
|
||||
config.pin_d1 = Y3_GPIO_NUM;
|
||||
config.pin_d2 = Y4_GPIO_NUM;
|
||||
config.pin_d3 = Y5_GPIO_NUM;
|
||||
config.pin_d4 = Y6_GPIO_NUM;
|
||||
config.pin_d5 = Y7_GPIO_NUM;
|
||||
config.pin_d6 = Y8_GPIO_NUM;
|
||||
config.pin_d7 = Y9_GPIO_NUM;
|
||||
config.pin_xclk = XCLK_GPIO_NUM;
|
||||
config.pin_pclk = PCLK_GPIO_NUM;
|
||||
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||
config.pin_href = HREF_GPIO_NUM;
|
||||
config.pin_sscb_sda = SIOD_GPIO_NUM;
|
||||
config.pin_sscb_scl = SIOC_GPIO_NUM;
|
||||
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||
config.pin_reset = RESET_GPIO_NUM;
|
||||
config.xclk_freq_hz = 20000000;
|
||||
config.pixel_format = PIXFORMAT_JPEG;
|
||||
|
||||
if(psramFound()){
|
||||
config.frame_size = FRAMESIZE_UXGA;
|
||||
config.jpeg_quality = 10;
|
||||
config.fb_count = 2;
|
||||
} else {
|
||||
config.frame_size = FRAMESIZE_SVGA;
|
||||
config.jpeg_quality = 12;
|
||||
config.fb_count = 1;
|
||||
}
|
||||
|
||||
// Camera init
|
||||
esp_err_t err = esp_camera_init(&config);
|
||||
if (err != ESP_OK) {
|
||||
Serial.printf("Camera init failed with error 0x%x", err);
|
||||
return;
|
||||
}
|
||||
// Wi-Fi connection
|
||||
//WiFi.begin(ssid, password);
|
||||
WiFi.begin(ssid);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected");
|
||||
|
||||
Serial.print("Camera Stream Ready! Go to: http://");
|
||||
Serial.print(WiFi.localIP());
|
||||
|
||||
// Start streaming web server
|
||||
startCameraServer();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(1);
|
||||
}
|
@ -0,0 +1,583 @@
|
||||
/*
|
||||
ESP32-CAM QR code Reader
|
||||
Author : ChungYi Fu (Kaohsiung, Taiwan) 2021-8-13 20:00
|
||||
https://www.facebook.com/francefu
|
||||
|
||||
Refer to the code
|
||||
https://github.com/alvarowolfx/ESP32QRCodeReader
|
||||
|
||||
自訂指令格式 http://192.168.xxx.xxx/control?cmd=P1;P2;P3;P4;P5;P6;P7;P8;P9
|
||||
|
||||
http://192.168.xxx.xxx/?ip //取得APIP, STAIP
|
||||
http://192.168.xxx.xxx/?mac //取得MAC位址
|
||||
http://192.168.xxx.xxx/?digitalwrite=pin;value //數位輸出
|
||||
http://192.168.xxx.xxx/?analogwrite=pin;value //類比輸出
|
||||
http://192.168.xxx.xxx/?digitalread=pin //數位讀取
|
||||
http://192.168.xxx.xxx/?analogread=pin //類比讀取
|
||||
http://192.168.xxx.xxx/?touchread=pin //觸碰讀取
|
||||
http://192.168.xxx.xxx/?restart //重啟電源
|
||||
http://192.168.xxx.xxx/?flash=value //閃光燈 value= 0~255
|
||||
http://192.168.xxx.xxx/?servo=pin;value //伺服馬達 value= 0~180
|
||||
http://192.168.xxx.xxx/?relay=pin;value //繼電器 value = 0, 1
|
||||
http://192.168.xxx.xxx/?uart=value //序列埠
|
||||
*/
|
||||
|
||||
//輸入WIFI連線帳號密碼
|
||||
const char* ssid = "*****";
|
||||
const char* password = "*****";
|
||||
|
||||
//輸入AP端連線帳號密碼 http://192.168.4.1
|
||||
const char* apssid = "esp32-cam";
|
||||
const char* appassword = "12345678"; //AP密碼至少要8個字元以上
|
||||
|
||||
String Feedback=""; //回傳客戶端訊息
|
||||
//指令參數值
|
||||
String Command="",cmd="",P1="",P2="",P3="",P4="",P5="",P6="",P7="",P8="",P9="";
|
||||
//指令拆解狀態值
|
||||
byte ReceiveState=0,cmdState=1,strState=1,questionstate=0,equalstate=0,semicolonstate=0;
|
||||
|
||||
#include <WiFi.h>
|
||||
#include "esp_camera.h" //視訊函式
|
||||
#include "soc/soc.h" //用於電源不穩不重開機
|
||||
#include "soc/rtc_cntl_reg.h" //用於電源不穩不重開機
|
||||
#include "quirc.h"
|
||||
|
||||
TaskHandle_t Task;
|
||||
|
||||
//ESP32-CAM 安信可模組腳位設定
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 0
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 21
|
||||
#define Y4_GPIO_NUM 19
|
||||
#define Y3_GPIO_NUM 18
|
||||
#define Y2_GPIO_NUM 5
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
struct QRCodeData
|
||||
{
|
||||
bool valid;
|
||||
int dataType;
|
||||
uint8_t payload[1024];
|
||||
int payloadLen;
|
||||
};
|
||||
|
||||
struct quirc *q = NULL;
|
||||
uint8_t *image = NULL;
|
||||
camera_fb_t * fb = NULL;
|
||||
struct quirc_code code;
|
||||
struct quirc_data data;
|
||||
quirc_decode_error_t err;
|
||||
struct QRCodeData qrCodeData;
|
||||
String QRCodeResult = "";
|
||||
|
||||
WiFiServer server(80);
|
||||
WiFiClient client;
|
||||
|
||||
camera_config_t config;
|
||||
|
||||
void setup() {
|
||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //關閉電源不穩就重開機的設定
|
||||
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true); //開啟診斷輸出
|
||||
Serial.println();
|
||||
|
||||
//視訊組態設定 https://github.com/espressif/esp32-camera/blob/master/driver/include/esp_camera.h
|
||||
config.ledc_channel = LEDC_CHANNEL_0;
|
||||
config.ledc_timer = LEDC_TIMER_0;
|
||||
config.pin_d0 = Y2_GPIO_NUM;
|
||||
config.pin_d1 = Y3_GPIO_NUM;
|
||||
config.pin_d2 = Y4_GPIO_NUM;
|
||||
config.pin_d3 = Y5_GPIO_NUM;
|
||||
config.pin_d4 = Y6_GPIO_NUM;
|
||||
config.pin_d5 = Y7_GPIO_NUM;
|
||||
config.pin_d6 = Y8_GPIO_NUM;
|
||||
config.pin_d7 = Y9_GPIO_NUM;
|
||||
config.pin_xclk = XCLK_GPIO_NUM;
|
||||
config.pin_pclk = PCLK_GPIO_NUM;
|
||||
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||
config.pin_href = HREF_GPIO_NUM;
|
||||
config.pin_sscb_sda = SIOD_GPIO_NUM;
|
||||
config.pin_sscb_scl = SIOC_GPIO_NUM;
|
||||
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||
config.pin_reset = RESET_GPIO_NUM;
|
||||
config.xclk_freq_hz = 10000000;
|
||||
config.pixel_format = PIXFORMAT_GRAYSCALE;
|
||||
config.frame_size = FRAMESIZE_QVGA;
|
||||
config.jpeg_quality = 15;
|
||||
config.fb_count = 1;
|
||||
|
||||
//視訊初始化
|
||||
esp_err_t err = esp_camera_init(&config);
|
||||
if (err != ESP_OK) {
|
||||
Serial.printf("Camera init failed with error 0x%x", err);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
s->set_framesize(s, FRAMESIZE_QVGA);
|
||||
|
||||
//s->set_vflip(s, 1); //垂直翻轉
|
||||
//s->set_hmirror(s, 1); //水平鏡像
|
||||
|
||||
//閃光燈(GPIO4)
|
||||
ledcAttachPin(4, 4);
|
||||
ledcSetup(4, 5000, 8);
|
||||
|
||||
WiFi.mode(WIFI_AP_STA); //其他模式 WiFi.mode(WIFI_AP); WiFi.mode(WIFI_STA);
|
||||
|
||||
//指定Client端靜態IP
|
||||
//WiFi.config(IPAddress(192, 168, 201, 100), IPAddress(192, 168, 201, 2), IPAddress(255, 255, 255, 0));
|
||||
|
||||
for (int i=0;i<2;i++) {
|
||||
WiFi.begin(ssid, password); //執行網路連線
|
||||
|
||||
delay(1000);
|
||||
Serial.println("");
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(ssid);
|
||||
|
||||
long int StartTime=millis();
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
if ((StartTime+5000) < millis()) break; //等待10秒連線
|
||||
}
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED) { //若連線成功
|
||||
WiFi.softAP((WiFi.localIP().toString()+"_"+(String)apssid).c_str(), appassword); //設定SSID顯示客戶端IP
|
||||
Serial.println("");
|
||||
Serial.println("STAIP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
Serial.println("");
|
||||
|
||||
for (int i=0;i<5;i++) { //若連上WIFI設定閃光燈快速閃爍
|
||||
ledcWrite(4,10);
|
||||
delay(200);
|
||||
ledcWrite(4,0);
|
||||
delay(200);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED) { //若連線失敗
|
||||
WiFi.softAP((WiFi.softAPIP().toString()+"_"+(String)apssid).c_str(), appassword);
|
||||
|
||||
for (int i=0;i<2;i++) { //若連不上WIFI設定閃光燈慢速閃爍
|
||||
ledcWrite(4,10);
|
||||
delay(1000);
|
||||
ledcWrite(4,0);
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
//指定AP端IP
|
||||
//WiFi.softAPConfig(IPAddress(192, 168, 4, 1), IPAddress(192, 168, 4, 1), IPAddress(255, 255, 255, 0));
|
||||
Serial.println("");
|
||||
Serial.println("APIP address: ");
|
||||
Serial.println(WiFi.softAPIP());
|
||||
Serial.println("");
|
||||
|
||||
//設定閃光燈為低電位
|
||||
pinMode(4, OUTPUT);
|
||||
digitalWrite(4, LOW);
|
||||
|
||||
server.begin();
|
||||
|
||||
xTaskCreatePinnedToCore(
|
||||
QRCodeReader, /* Task function. */
|
||||
"Task", /* name of task. */
|
||||
10000, /* Stack size of task */
|
||||
NULL, /* parameter of the task */
|
||||
1, /* priority of the task */
|
||||
&Task, /* Task handle to keep track of created task */
|
||||
0); /* pin task to core 0 */
|
||||
|
||||
Serial.print("listenConnection running on core ");
|
||||
Serial.println(xPortGetCoreID());
|
||||
}
|
||||
|
||||
void loop() {
|
||||
listenConnection();
|
||||
}
|
||||
|
||||
void QRCodeReader( void * pvParameters ){
|
||||
Serial.print("QRCodeReader running on core ");
|
||||
Serial.println(xPortGetCoreID());
|
||||
|
||||
while(1){
|
||||
q = quirc_new();
|
||||
if (q == NULL){
|
||||
Serial.print("can't create quirc object\r\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
fb = esp_camera_fb_get();
|
||||
if (!fb)
|
||||
{
|
||||
Serial.println("Camera capture failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
//Serial.printf("quirc_begin\r\n");
|
||||
quirc_resize(q, fb->width, fb->height);
|
||||
image = quirc_begin(q, NULL, NULL);
|
||||
//Serial.printf("Frame w h len: %d, %d, %d \r\n", fb->width, fb->height, fb->len);
|
||||
memcpy(image, fb->buf, fb->len);
|
||||
quirc_end(q);
|
||||
//Serial.printf("quirc_end\r\n");
|
||||
|
||||
int count = quirc_count(q);
|
||||
if (count > 0) {
|
||||
Serial.println(count);
|
||||
quirc_extract(q, 0, &code);
|
||||
err = quirc_decode(&code, &data);
|
||||
|
||||
if (err){
|
||||
Serial.println("Decoding FAILED");
|
||||
QRCodeResult = "Decoding FAILED";
|
||||
} else {
|
||||
Serial.printf("Decoding successful:\n");
|
||||
dumpData(&data);
|
||||
/*
|
||||
qrCodeData.dataType = data.data_type;
|
||||
for (int j = 0; j < data.payload_len; j++)
|
||||
{
|
||||
qrCodeData.payload[j] = data.payload[j];
|
||||
}
|
||||
qrCodeData.valid = true;
|
||||
qrCodeData.payload[data.payload_len] = '\0';
|
||||
qrCodeData.payloadLen = data.payload_len;
|
||||
*/
|
||||
//vTaskDelay(3000/portTICK_RATE_MS);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
esp_camera_fb_return(fb);
|
||||
fb = NULL;
|
||||
image = NULL;
|
||||
quirc_destroy(q);
|
||||
}
|
||||
}
|
||||
|
||||
void dumpData(const struct quirc_data *data)
|
||||
{
|
||||
Serial.printf("Version: %d\n", data->version);
|
||||
Serial.printf("ECC level: %c\n", "MLHQ"[data->ecc_level]);
|
||||
Serial.printf("Mask: %d\n", data->mask);
|
||||
Serial.printf("Length: %d\n", data->payload_len);
|
||||
Serial.printf("Payload: %s\n", data->payload);
|
||||
|
||||
QRCodeResult = (const char *)data->payload;
|
||||
}
|
||||
|
||||
//執行自訂指令
|
||||
void ExecuteCommand() {
|
||||
//Serial.println("");
|
||||
//Serial.println("Command: "+Command);
|
||||
if (cmd!="getstill") {
|
||||
Serial.println("cmd= "+cmd+" ,P1= "+P1+" ,P2= "+P2+" ,P3= "+P3+" ,P4= "+P4+" ,P5= "+P5+" ,P6= "+P6+" ,P7= "+P7+" ,P8= "+P8+" ,P9= "+P9);
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
//自訂指令區塊 http://192.168.xxx.xxx?cmd=P1;P2;P3;P4;P5;P6;P7;P8;P9
|
||||
if (cmd=="your cmd") {
|
||||
// You can do anything
|
||||
// Feedback="<font color=\"red\">Hello World</font>"; //可為一般文字或HTML語法
|
||||
}
|
||||
else if (cmd=="ip") { //查詢APIP, STAIP
|
||||
Feedback="AP IP: "+WiFi.softAPIP().toString();
|
||||
Feedback+="<br>";
|
||||
Feedback+="STA IP: "+WiFi.localIP().toString();
|
||||
}
|
||||
else if (cmd=="mac") { //查詢MAC位址
|
||||
Feedback="STA MAC: "+WiFi.macAddress();
|
||||
}
|
||||
else if (cmd=="restart") { //重設WIFI連線
|
||||
ESP.restart();
|
||||
}
|
||||
else if (cmd=="digitalwrite") { //數位輸出
|
||||
ledcDetachPin(P1.toInt());
|
||||
pinMode(P1.toInt(), OUTPUT);
|
||||
digitalWrite(P1.toInt(), P2.toInt());
|
||||
}
|
||||
else if (cmd=="digitalread") { //數位輸入
|
||||
Feedback=String(digitalRead(P1.toInt()));
|
||||
}
|
||||
else if (cmd=="analogwrite") { //類比輸出
|
||||
if (P1=="4") {
|
||||
ledcAttachPin(4, 4);
|
||||
ledcSetup(4, 5000, 8);
|
||||
ledcWrite(4,P2.toInt());
|
||||
}
|
||||
else {
|
||||
ledcAttachPin(P1.toInt(), 9);
|
||||
ledcSetup(9, 5000, 8);
|
||||
ledcWrite(9,P2.toInt());
|
||||
}
|
||||
}
|
||||
else if (cmd=="analogread") { //類比讀取
|
||||
Feedback=String(analogRead(P1.toInt()));
|
||||
}
|
||||
else if (cmd=="touchread") { //觸碰讀取
|
||||
Feedback=String(touchRead(P1.toInt()));
|
||||
}
|
||||
else if (cmd=="framesize") { //解析度
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int val = P1.toInt();
|
||||
s->set_framesize(s, (framesize_t)val);
|
||||
}
|
||||
else if (cmd=="quality") { //畫質
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int val = P1.toInt();
|
||||
s->set_quality(s, val);
|
||||
}
|
||||
else if (cmd=="contrast") { //對比
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int val = P1.toInt();
|
||||
s->set_contrast(s, val);
|
||||
}
|
||||
else if (cmd=="brightness") { //亮度
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int val = P1.toInt();
|
||||
s->set_brightness(s, val);
|
||||
}
|
||||
else if (cmd=="hmirror") { //水平鏡像
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int val = P1.toInt();
|
||||
s->set_hmirror(s, val);
|
||||
}
|
||||
else if (cmd=="vflip") { //垂直翻轉
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int val = P1.toInt();
|
||||
s->set_vflip(s, val);
|
||||
}
|
||||
else if (cmd=="serial") { //序列埠
|
||||
Serial.print(P1);
|
||||
}
|
||||
else if (cmd=="restart") { //重啟電源
|
||||
ESP.restart();
|
||||
}
|
||||
else if (cmd=="flash") { //閃光燈
|
||||
ledcAttachPin(4, 4);
|
||||
ledcSetup(4, 5000, 8);
|
||||
int val = P1.toInt();
|
||||
ledcWrite(4,val);
|
||||
}
|
||||
else if(cmd=="servo") { //伺服馬達 (0-180)
|
||||
ledcAttachPin(P1.toInt(), 3);
|
||||
ledcSetup(3, 50, 16);
|
||||
|
||||
int val = 7864-P2.toInt()*34.59;
|
||||
if (val > 7864)
|
||||
val = 7864;
|
||||
else if (val < 1638)
|
||||
val = 1638;
|
||||
ledcWrite(3, val);
|
||||
}
|
||||
else if (cmd=="relay") { //繼電器
|
||||
pinMode(P1.toInt(), OUTPUT);
|
||||
digitalWrite(13, P2.toInt());
|
||||
}
|
||||
else {
|
||||
Feedback="Command is not defined.";
|
||||
}
|
||||
|
||||
if (Feedback=="") Feedback=Command;
|
||||
}
|
||||
|
||||
|
||||
//自訂網頁首頁管理介面
|
||||
static const char PROGMEM INDEX_HTML[] = R"rawliteral(
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" width="320" height="240"></canvas><br>
|
||||
Flash<input type="range" id="flash" min="0" max="255" value="0">
|
||||
<input type="button" value="Get Still" onclick="getStill();"><br>
|
||||
<div id="result" style="color:red"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
var flash = document.getElementById('flash');
|
||||
var result = document.getElementById('result');
|
||||
|
||||
flash.onchange = function() {
|
||||
var query = document.location.origin+"/?flash="+flash.value;
|
||||
fetch(query);
|
||||
}
|
||||
|
||||
function getStill() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/?getstill", true);
|
||||
xhr.responseType = "arraybuffer";
|
||||
|
||||
xhr.onload = function (oEvent) {
|
||||
var arrayBuffer = xhr.response; // Note: not xhr.responseText
|
||||
if (arrayBuffer) {
|
||||
var byteArray = new Uint8Array(arrayBuffer);
|
||||
var imgData=context.getImageData(0,0,canvas.width,canvas.height);
|
||||
var val = 0;
|
||||
for (var i=0;i<imgData.data.length;i+=4) {
|
||||
val = parseInt(byteArray[i/4], 10);
|
||||
imgData.data[i]=val;
|
||||
imgData.data[i+1]=val;
|
||||
imgData.data[i+2]=val;
|
||||
imgData.data[i+3]=255;
|
||||
}
|
||||
context.putImageData(imgData,0,0);
|
||||
setTimeout(function(){getStill();}, 100);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(null);
|
||||
}
|
||||
</script>
|
||||
)rawliteral";
|
||||
|
||||
void listenConnection() {
|
||||
Feedback="";Command="";cmd="";P1="";P2="";P3="";P4="";P5="";P6="";P7="";P8="";P9="";
|
||||
ReceiveState=0,cmdState=1,strState=1,questionstate=0,equalstate=0,semicolonstate=0;
|
||||
|
||||
client = server.available();
|
||||
|
||||
if (client) {
|
||||
String currentLine = "";
|
||||
|
||||
while (client.connected()) {
|
||||
if (client.available()) {
|
||||
char c = client.read();
|
||||
getCommand(c); //將緩衝區取得的字元拆解出指令參數
|
||||
if (c == '\n') {
|
||||
if (currentLine.length() == 0) {
|
||||
if (cmd=="getstill") {
|
||||
getStill();
|
||||
} else {
|
||||
mainPage();
|
||||
}
|
||||
Feedback="";
|
||||
break;
|
||||
} else {
|
||||
currentLine = "";
|
||||
}
|
||||
} else if (c != '\r') {
|
||||
currentLine += c;
|
||||
}
|
||||
|
||||
if ((currentLine.indexOf("?")!=-1)&&(currentLine.indexOf(" HTTP")!=-1)) {
|
||||
if (Command.indexOf("stop")!=-1) { //若指令中含關鍵字stop立即斷線 -> http://192.168.xxx.xxx?cmd=aaa;bbb;ccc;stop
|
||||
client.println();
|
||||
client.println();
|
||||
client.stop();
|
||||
}
|
||||
currentLine="";
|
||||
Feedback="";
|
||||
ExecuteCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
delay(1);
|
||||
client.stop();
|
||||
}
|
||||
}
|
||||
|
||||
void mainPage() {
|
||||
//回傳HTML首頁或Feedback
|
||||
client.println("HTTP/1.1 200 OK");
|
||||
client.println("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
|
||||
client.println("Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS");
|
||||
client.println("Content-Type: text/html; charset=utf-8");
|
||||
client.println("Access-Control-Allow-Origin: *");
|
||||
client.println("Connection: close");
|
||||
client.println();
|
||||
|
||||
String Data="";
|
||||
if (cmd!="")
|
||||
Data = Feedback;
|
||||
else {
|
||||
Data = String((const char *)INDEX_HTML);
|
||||
}
|
||||
int Index;
|
||||
for (Index = 0; Index < Data.length(); Index = Index+1024) {
|
||||
client.print(Data.substring(Index, Index+1024));
|
||||
}
|
||||
}
|
||||
|
||||
void getStill() {
|
||||
camera_fb_t * fb = NULL;
|
||||
fb = esp_camera_fb_get();
|
||||
if(!fb) {
|
||||
Serial.println("Camera capture failed");
|
||||
return;
|
||||
}
|
||||
uint8_t *fbBuf = fb->buf;
|
||||
size_t fbLen = fb->len;
|
||||
|
||||
client.println("HTTP/1.1 200 OK");
|
||||
client.println("Access-Control-Allow-Origin: *");
|
||||
client.println("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
|
||||
client.println("Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS");
|
||||
client.println("Content-Type: application/octet-stream");
|
||||
client.println();
|
||||
|
||||
for (size_t n=0;n<fbLen;n=n+1024) {
|
||||
if (n+1024<fbLen) {
|
||||
client.write(fbBuf, 1024);
|
||||
fbBuf += 1024;
|
||||
}
|
||||
else if (fbLen%1024>0) {
|
||||
size_t remainder = fbLen%1024;
|
||||
client.write(fbBuf, remainder);
|
||||
}
|
||||
}
|
||||
esp_camera_fb_return(fb);
|
||||
|
||||
pinMode(4, OUTPUT);
|
||||
digitalWrite(4, LOW);
|
||||
}
|
||||
|
||||
//拆解命令字串置入變數
|
||||
void getCommand(char c) {
|
||||
if (c=='?') ReceiveState=1;
|
||||
if ((c==' ')||(c=='\r')||(c=='\n')) ReceiveState=0;
|
||||
|
||||
if (ReceiveState==1)
|
||||
{
|
||||
Command=Command+String(c);
|
||||
|
||||
if (c=='=') cmdState=0;
|
||||
if (c==';') strState++;
|
||||
|
||||
if ((cmdState==1)&&((c!='?')||(questionstate==1))) cmd=cmd+String(c);
|
||||
if ((cmdState==0)&&(strState==1)&&((c!='=')||(equalstate==1))) P1=P1+String(c);
|
||||
if ((cmdState==0)&&(strState==2)&&(c!=';')) P2=P2+String(c);
|
||||
if ((cmdState==0)&&(strState==3)&&(c!=';')) P3=P3+String(c);
|
||||
if ((cmdState==0)&&(strState==4)&&(c!=';')) P4=P4+String(c);
|
||||
if ((cmdState==0)&&(strState==5)&&(c!=';')) P5=P5+String(c);
|
||||
if ((cmdState==0)&&(strState==6)&&(c!=';')) P6=P6+String(c);
|
||||
if ((cmdState==0)&&(strState==7)&&(c!=';')) P7=P7+String(c);
|
||||
if ((cmdState==0)&&(strState==8)&&(c!=';')) P8=P8+String(c);
|
||||
if ((cmdState==0)&&(strState>=9)&&((c!=';')||(semicolonstate==1))) P9=P9+String(c);
|
||||
|
||||
if (c=='?') questionstate=1;
|
||||
if (c=='=') equalstate=1;
|
||||
if ((strState>=9)&&(c==';')) semicolonstate=1;
|
||||
}
|
||||
}
|
16
libraries/ESP32QRCodeReader_Page_original/LICENSE
Normal file
16
libraries/ESP32QRCodeReader_Page_original/LICENSE
Normal file
@ -0,0 +1,16 @@
|
||||
quirc -- QR-code recognition library
|
||||
Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all
|
||||
copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
193
libraries/ESP32QRCodeReader_Page_original/README.md
Normal file
193
libraries/ESP32QRCodeReader_Page_original/README.md
Normal file
@ -0,0 +1,193 @@
|
||||
Quirc
|
||||
=====
|
||||
|
||||
QR codes are a type of high-density matrix barcodes, and quirc is a library for
|
||||
extracting and decoding them from images. It has several features which make it
|
||||
a good choice for this purpose:
|
||||
|
||||
* It is fast enough to be used with realtime video: extracting and decoding
|
||||
from VGA frame takes about 50 ms on a modern x86 core.
|
||||
|
||||
* It has a robust and tolerant recognition algorithm. It can correctly
|
||||
recognise and decode QR codes which are rotated and/or oblique to the camera.
|
||||
It can also distinguish and decode multiple codes within the same image.
|
||||
|
||||
* It is easy to use, with a simple API described in a single commented header
|
||||
file (see below for an overview).
|
||||
|
||||
* It is small and easily embeddable, with no dependencies other than standard C
|
||||
functions.
|
||||
|
||||
* It has a very small memory footprint: one byte per image pixel, plus a few kB
|
||||
per decoder object.
|
||||
|
||||
* It uses no global mutable state, and is safe to use in a multithreaded
|
||||
application.
|
||||
|
||||
* BSD-licensed, with almost no restrictions regarding use and/or modification.
|
||||
|
||||
The distribution comes with, in addition to the library, several test programs.
|
||||
While the core library is very portable, these programs have some additional
|
||||
dependencies. All of them require libjpeg, and two (`quirc-demo` and `inspect`)
|
||||
require SDL. The camera demos use Linux-specific APIs:
|
||||
|
||||
### quirc-demo
|
||||
|
||||
This is an real-time demo which requires a camera and a graphical display. The
|
||||
video stream is displayed on screen as it's received, and any QR codes
|
||||
recognised are highlighted in the image, with the decoded information both
|
||||
displayed on the image and printed on stdout.
|
||||
|
||||
### quirc-scanner
|
||||
|
||||
This program turns your camera into a barcode scanner. It's almost the same as
|
||||
the `demo` application, but it doesn't display the video stream, and thus
|
||||
doesn't require a graphical display.
|
||||
|
||||
### qrtest
|
||||
|
||||
This test is used to evaluate the performance of library. Given a directory
|
||||
tree containing a bunch of JPEG images, it will attempt to locate and decode QR
|
||||
codes in each image. Speed and success statistics are collected and printed on
|
||||
stdout.
|
||||
|
||||
### inspect
|
||||
|
||||
This test is used for debugging. Given a single JPEG image, it will display a
|
||||
diagram showing the internal state of the decoder as well as printing
|
||||
additional information on stdout.
|
||||
|
||||
Installation
|
||||
------------
|
||||
To build the library and associated demos/tests, type `make`. If you need to
|
||||
decode "large" image files build with `CFLAGS="-DQUIRC_MAX_REGIONS=65534" make`
|
||||
instead. Note that this will increase the memory usage, it is discouraged for
|
||||
low resource devices (i.e. embedded).
|
||||
|
||||
Type `make install` to install the library, header file and camera demos.
|
||||
|
||||
You can specify one or several of the following targets if you don't want, or
|
||||
are unable to build everything:
|
||||
|
||||
* libquirc.a
|
||||
* libquirc.so
|
||||
* qrtest
|
||||
* inspect
|
||||
* quirc-scanner
|
||||
* quirc-demo
|
||||
|
||||
Library use
|
||||
-----------
|
||||
All of the library's functionality is exposed through a single header file,
|
||||
which you should include:
|
||||
|
||||
```C
|
||||
#include <quirc.h>
|
||||
```
|
||||
|
||||
To decode images, you'll need to instantiate a `struct quirc` object, which is
|
||||
done with the `quirc_new` function. Later, when you no longer need to decode
|
||||
anything, you should release the allocated memory with `quirc_destroy`:
|
||||
|
||||
```C
|
||||
struct quirc *qr;
|
||||
|
||||
qr = quirc_new();
|
||||
if (!qr) {
|
||||
perror("Failed to allocate memory");
|
||||
abort();
|
||||
}
|
||||
|
||||
/* ... */
|
||||
|
||||
quirc_destroy(qr);
|
||||
```
|
||||
|
||||
Having obtained a decoder object, you need to set the image size that you'll be
|
||||
working with, which is done using `quirc_resize`:
|
||||
|
||||
```C
|
||||
if (quirc_resize(qr, 640, 480) < 0) {
|
||||
perror("Failed to allocate video memory");
|
||||
abort();
|
||||
}
|
||||
```
|
||||
|
||||
`quirc_resize` and `quirc_new` are the only library functions which allocate
|
||||
memory. If you plan to process a series of frames (or a video stream), you
|
||||
probably want to allocate and size a single decoder and hold onto it to process
|
||||
each frame.
|
||||
|
||||
Processing frames is done in two stages. The first stage is an
|
||||
image-recognition stage called identification, which takes a grayscale image
|
||||
and searches for QR codes. Using `quirc_begin` and `quirc_end`, you can feed a
|
||||
grayscale image directly into the buffer that `quirc` uses for image
|
||||
processing:
|
||||
|
||||
```C
|
||||
uint8_t *image;
|
||||
int w, h;
|
||||
|
||||
image = quirc_begin(qr, &w, &h);
|
||||
|
||||
/* Fill out the image buffer here.
|
||||
* image is a pointer to a w*h bytes.
|
||||
* One byte per pixel, w pixels per line, h lines in the buffer.
|
||||
*/
|
||||
|
||||
quirc_end(qr);
|
||||
```
|
||||
|
||||
Note that `quirc_begin` simply returns a pointer to a previously allocated
|
||||
buffer. The buffer will contain uninitialized data. After the call to
|
||||
`quirc_end`, the decoder holds a list of detected QR codes which can be queried
|
||||
via `quirc_count` and `quirc_extract`.
|
||||
|
||||
At this point, the second stage of processing occurs -- decoding. This is done
|
||||
via the call to `quirc_decode`, which is not associated with a decoder object.
|
||||
|
||||
```C
|
||||
int num_codes;
|
||||
int i;
|
||||
|
||||
/* We've previously fed an image to the decoder via
|
||||
* quirc_begin/quirc_end.
|
||||
*/
|
||||
|
||||
num_codes = quirc_count(qr);
|
||||
for (i = 0; i < num_codes; i++) {
|
||||
struct quirc_code code;
|
||||
struct quirc_data data;
|
||||
quirc_decode_error_t err;
|
||||
|
||||
quirc_extract(qr, i, &code);
|
||||
|
||||
/* Decoding stage */
|
||||
err = quirc_decode(&code, &data);
|
||||
if (err)
|
||||
printf("DECODE FAILED: %s\n", quirc_strerror(err));
|
||||
else
|
||||
printf("Data: %s\n", data.payload);
|
||||
}
|
||||
```
|
||||
|
||||
`quirc_code` and `quirc_data` are flat structures which don't need to be
|
||||
initialized or freed after use.
|
||||
|
||||
Copyright
|
||||
---------
|
||||
Copyright (C) 2010-2012 Daniel Beer <<dlbeer@gmail.com>>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all
|
||||
copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
85
libraries/ESP32QRCodeReader_Page_original/collections.c
Normal file
85
libraries/ESP32QRCodeReader_Page_original/collections.c
Normal file
@ -0,0 +1,85 @@
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2017 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "collections.h"
|
||||
#define CHAR_BITS (sizeof(char) * 8)
|
||||
#define CHAR_MASK (CHAR_BITS - 1)
|
||||
#define CHAR_SHIFT IM_LOG2(CHAR_MASK)
|
||||
|
||||
//////////
|
||||
// lifo //
|
||||
//////////
|
||||
|
||||
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len)
|
||||
{
|
||||
ptr->len = 0;
|
||||
ptr->size = size;
|
||||
ptr->data_len = data_len;
|
||||
ptr->data = (char *)ps_malloc(size * data_len);
|
||||
}
|
||||
|
||||
void lifo_alloc_all(lifo_t *ptr, size_t *size, size_t data_len)
|
||||
{
|
||||
ptr->data = (char *)ps_malloc(255);
|
||||
ptr->data_len = data_len;
|
||||
ptr->size = 255 / data_len;
|
||||
ptr->len = 0;
|
||||
*size = ptr->size;
|
||||
}
|
||||
|
||||
void lifo_free(lifo_t *ptr)
|
||||
{
|
||||
if (ptr->data)
|
||||
{
|
||||
free(ptr->data);
|
||||
}
|
||||
}
|
||||
|
||||
void lifo_clear(lifo_t *ptr)
|
||||
{
|
||||
ptr->len = 0;
|
||||
}
|
||||
|
||||
size_t lifo_size(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len;
|
||||
}
|
||||
|
||||
bool lifo_is_not_empty(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len;
|
||||
}
|
||||
|
||||
bool lifo_is_not_full(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len != ptr->size;
|
||||
}
|
||||
|
||||
void lifo_enqueue(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(ptr->data + (ptr->len * ptr->data_len), data, ptr->data_len);
|
||||
|
||||
ptr->len += 1;
|
||||
}
|
||||
|
||||
void lifo_dequeue(lifo_t *ptr, void *data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
memcpy(data, ptr->data + ((ptr->len - 1) * ptr->data_len), ptr->data_len);
|
||||
}
|
||||
|
||||
ptr->len -= 1;
|
||||
}
|
||||
|
||||
void lifo_poke(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(ptr->data + (ptr->len * ptr->data_len), data, ptr->data_len);
|
||||
}
|
||||
|
||||
void lifo_peek(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(data, ptr->data + ((ptr->len - 1) * ptr->data_len), ptr->data_len);
|
||||
}
|
33
libraries/ESP32QRCodeReader_Page_original/collections.h
Normal file
33
libraries/ESP32QRCodeReader_Page_original/collections.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2017 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef __COLLECTIONS_H__
|
||||
#define __COLLECTIONS_H__
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
//////////
|
||||
// lifo //
|
||||
//////////
|
||||
|
||||
typedef struct lifo
|
||||
{
|
||||
size_t len, size, data_len;
|
||||
char *data;
|
||||
}
|
||||
__attribute__((aligned(8))) lifo_t;
|
||||
|
||||
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len);
|
||||
void lifo_alloc_all(lifo_t *ptr, size_t *size, size_t data_len);
|
||||
void lifo_free(lifo_t *ptr);
|
||||
void lifo_clear(lifo_t *ptr);
|
||||
size_t lifo_size(lifo_t *ptr);
|
||||
bool lifo_is_not_empty(lifo_t *ptr);
|
||||
bool lifo_is_not_full(lifo_t *ptr);
|
||||
void lifo_enqueue(lifo_t *ptr, void *data);
|
||||
void lifo_dequeue(lifo_t *ptr, void *data);
|
||||
void lifo_poke(lifo_t *ptr, void *data);
|
||||
void lifo_peek(lifo_t *ptr, void *data);
|
||||
|
||||
#endif /* __COLLECTIONS_H__ */
|
983
libraries/ESP32QRCodeReader_Page_original/decode.c
Normal file
983
libraries/ESP32QRCodeReader_Page_original/decode.c
Normal file
@ -0,0 +1,983 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "quirc_internal.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_POLY 64
|
||||
|
||||
/************************************************************************
|
||||
* Galois fields
|
||||
*/
|
||||
|
||||
struct galois_field
|
||||
{
|
||||
int p;
|
||||
const uint8_t *log;
|
||||
const uint8_t *exp;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
static const uint8_t gf16_exp[16] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x03, 0x06, 0x0c, 0x0b,
|
||||
0x05, 0x0a, 0x07, 0x0e, 0x0f, 0x0d, 0x09, 0x01};
|
||||
|
||||
static const uint8_t gf16_log[16] = {
|
||||
0x00, 0x0f, 0x01, 0x04, 0x02, 0x08, 0x05, 0x0a,
|
||||
0x03, 0x0e, 0x09, 0x07, 0x06, 0x0d, 0x0b, 0x0c};
|
||||
|
||||
static const struct galois_field gf16 = {
|
||||
.p = 15,
|
||||
.log = gf16_log,
|
||||
.exp = gf16_exp};
|
||||
|
||||
static const uint8_t gf256_exp[256] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
|
||||
0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
|
||||
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
|
||||
0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
|
||||
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
|
||||
0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
|
||||
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
|
||||
0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
|
||||
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
|
||||
0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
|
||||
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
|
||||
0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
|
||||
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
|
||||
0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
|
||||
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
|
||||
0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
|
||||
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
|
||||
0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
|
||||
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
|
||||
0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
|
||||
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
|
||||
0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
|
||||
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
|
||||
0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
|
||||
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
|
||||
0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
|
||||
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
|
||||
0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
|
||||
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
|
||||
0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
|
||||
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
|
||||
0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01};
|
||||
|
||||
static const uint8_t gf256_log[256] = {
|
||||
0x00, 0xff, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
|
||||
0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
|
||||
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
|
||||
0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
|
||||
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
|
||||
0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
|
||||
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
|
||||
0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
|
||||
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
|
||||
0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
|
||||
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
|
||||
0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
|
||||
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
|
||||
0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
|
||||
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
|
||||
0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
|
||||
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
|
||||
0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
|
||||
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
|
||||
0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
|
||||
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
|
||||
0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
|
||||
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
|
||||
0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
|
||||
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
|
||||
0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
|
||||
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
|
||||
0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
|
||||
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
|
||||
0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
|
||||
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
|
||||
0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf};
|
||||
|
||||
const static struct galois_field gf256 = {
|
||||
.p = 255,
|
||||
.log = gf256_log,
|
||||
.exp = gf256_exp};
|
||||
|
||||
/************************************************************************
|
||||
* Polynomial operations
|
||||
*/
|
||||
|
||||
static void poly_add(uint8_t *dst, const uint8_t *src, uint8_t c,
|
||||
int shift, const struct galois_field *gf)
|
||||
{
|
||||
int i;
|
||||
int log_c = gf->log[c];
|
||||
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_POLY; i++)
|
||||
{
|
||||
int p = i + shift;
|
||||
uint8_t v = src[i];
|
||||
|
||||
if (p < 0 || p >= MAX_POLY)
|
||||
continue;
|
||||
if (!v)
|
||||
continue;
|
||||
|
||||
dst[p] ^= gf->exp[(gf->log[v] + log_c) % gf->p];
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t poly_eval(const uint8_t *s, uint8_t x,
|
||||
const struct galois_field *gf)
|
||||
{
|
||||
int i;
|
||||
uint8_t sum = 0;
|
||||
uint8_t log_x = gf->log[x];
|
||||
|
||||
if (!x)
|
||||
return s[0];
|
||||
|
||||
for (i = 0; i < MAX_POLY; i++)
|
||||
{
|
||||
uint8_t c = s[i];
|
||||
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
sum ^= gf->exp[(gf->log[c] + log_x * i) % gf->p];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Berlekamp-Massey algorithm for finding error locator polynomials.
|
||||
*/
|
||||
|
||||
static void berlekamp_massey(const uint8_t *s, int N,
|
||||
const struct galois_field *gf,
|
||||
uint8_t *sigma)
|
||||
{
|
||||
uint8_t C[MAX_POLY];
|
||||
uint8_t B[MAX_POLY];
|
||||
int L = 0;
|
||||
int m = 1;
|
||||
uint8_t b = 1;
|
||||
int n;
|
||||
|
||||
memset(B, 0, sizeof(B));
|
||||
memset(C, 0, sizeof(C));
|
||||
B[0] = 1;
|
||||
C[0] = 1;
|
||||
|
||||
for (n = 0; n < N; n++)
|
||||
{
|
||||
uint8_t d = s[n];
|
||||
uint8_t mult;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= L; i++)
|
||||
{
|
||||
if (!(C[i] && s[n - i]))
|
||||
continue;
|
||||
|
||||
d ^= gf->exp[(gf->log[C[i]] +
|
||||
gf->log[s[n - i]]) %
|
||||
gf->p];
|
||||
}
|
||||
|
||||
mult = gf->exp[(gf->p - gf->log[b] + gf->log[d]) % gf->p];
|
||||
|
||||
if (!d)
|
||||
{
|
||||
m++;
|
||||
}
|
||||
else if (L * 2 <= n)
|
||||
{
|
||||
uint8_t T[MAX_POLY];
|
||||
|
||||
memcpy(T, C, sizeof(T));
|
||||
poly_add(C, B, mult, m, gf);
|
||||
memcpy(B, T, sizeof(B));
|
||||
L = n + 1 - L;
|
||||
b = d;
|
||||
m = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
poly_add(C, B, mult, m, gf);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(sigma, C, MAX_POLY);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Code stream error correction
|
||||
*
|
||||
* Generator polynomial for GF(2^8) is x^8 + x^4 + x^3 + x^2 + 1
|
||||
*/
|
||||
|
||||
static int block_syndromes(const uint8_t *data, int bs, int npar, uint8_t *s)
|
||||
{
|
||||
int nonzero = 0;
|
||||
int i;
|
||||
|
||||
memset(s, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < npar; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < bs; j++)
|
||||
{
|
||||
uint8_t c = data[bs - j - 1];
|
||||
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
s[i] ^= gf256_exp[((int)gf256_log[c] +
|
||||
i * j) %
|
||||
255];
|
||||
}
|
||||
|
||||
if (s[i])
|
||||
nonzero = 1;
|
||||
}
|
||||
|
||||
return nonzero;
|
||||
}
|
||||
|
||||
static void eloc_poly(uint8_t *omega,
|
||||
const uint8_t *s, const uint8_t *sigma,
|
||||
int npar)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(omega, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < npar; i++)
|
||||
{
|
||||
const uint8_t a = sigma[i];
|
||||
const uint8_t log_a = gf256_log[a];
|
||||
int j;
|
||||
|
||||
if (!a)
|
||||
continue;
|
||||
|
||||
for (j = 0; j + 1 < MAX_POLY; j++)
|
||||
{
|
||||
const uint8_t b = s[j + 1];
|
||||
|
||||
if (i + j >= npar)
|
||||
break;
|
||||
|
||||
if (!b)
|
||||
continue;
|
||||
|
||||
omega[i + j] ^=
|
||||
gf256_exp[(log_a + gf256_log[b]) % 255];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static quirc_decode_error_t correct_block(uint8_t *data,
|
||||
const struct quirc_rs_params *ecc)
|
||||
{
|
||||
int npar = ecc->bs - ecc->dw;
|
||||
uint8_t s[MAX_POLY];
|
||||
uint8_t sigma[MAX_POLY];
|
||||
uint8_t sigma_deriv[MAX_POLY];
|
||||
uint8_t omega[MAX_POLY];
|
||||
int i;
|
||||
|
||||
/* Compute syndrome vector */
|
||||
if (!block_syndromes(data, ecc->bs, npar, s))
|
||||
return QUIRC_SUCCESS;
|
||||
|
||||
berlekamp_massey(s, npar, &gf256, sigma);
|
||||
|
||||
/* Compute derivative of sigma */
|
||||
memset(sigma_deriv, 0, MAX_POLY);
|
||||
for (i = 0; i + 1 < MAX_POLY; i += 2)
|
||||
sigma_deriv[i] = sigma[i + 1];
|
||||
|
||||
/* Compute error evaluator polynomial */
|
||||
eloc_poly(omega, s, sigma, npar - 1);
|
||||
|
||||
/* Find error locations and magnitudes */
|
||||
for (i = 0; i < ecc->bs; i++)
|
||||
{
|
||||
uint8_t xinv = gf256_exp[255 - i];
|
||||
|
||||
if (!poly_eval(sigma, xinv, &gf256))
|
||||
{
|
||||
uint8_t sd_x = poly_eval(sigma_deriv, xinv, &gf256);
|
||||
uint8_t omega_x = poly_eval(omega, xinv, &gf256);
|
||||
uint8_t error = gf256_exp[(255 - gf256_log[sd_x] +
|
||||
gf256_log[omega_x]) %
|
||||
255];
|
||||
|
||||
data[ecc->bs - i - 1] ^= error;
|
||||
}
|
||||
}
|
||||
|
||||
if (block_syndromes(data, ecc->bs, npar, s))
|
||||
return QUIRC_ERROR_DATA_ECC;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Format value error correction
|
||||
*
|
||||
* Generator polynomial for GF(2^4) is x^4 + x + 1
|
||||
*/
|
||||
|
||||
#define FORMAT_MAX_ERROR 3
|
||||
#define FORMAT_SYNDROMES (FORMAT_MAX_ERROR * 2)
|
||||
#define FORMAT_BITS 15
|
||||
|
||||
static int format_syndromes(uint16_t u, uint8_t *s)
|
||||
{
|
||||
int i;
|
||||
int nonzero = 0;
|
||||
|
||||
memset(s, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < FORMAT_SYNDROMES; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
s[i] = 0;
|
||||
for (j = 0; j < FORMAT_BITS; j++)
|
||||
if (u & (1 << j))
|
||||
s[i] ^= gf16_exp[((i + 1) * j) % 15];
|
||||
|
||||
if (s[i])
|
||||
nonzero = 1;
|
||||
}
|
||||
|
||||
return nonzero;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t correct_format(uint16_t *f_ret)
|
||||
{
|
||||
uint16_t u = *f_ret;
|
||||
int i;
|
||||
uint8_t s[MAX_POLY];
|
||||
uint8_t sigma[MAX_POLY];
|
||||
|
||||
/* Evaluate U (received codeword) at each of alpha_1 .. alpha_6
|
||||
* to get S_1 .. S_6 (but we index them from 0).
|
||||
*/
|
||||
if (!format_syndromes(u, s))
|
||||
return QUIRC_SUCCESS;
|
||||
|
||||
berlekamp_massey(s, FORMAT_SYNDROMES, &gf16, sigma);
|
||||
|
||||
/* Now, find the roots of the polynomial */
|
||||
for (i = 0; i < 15; i++)
|
||||
if (!poly_eval(sigma, gf16_exp[15 - i], &gf16))
|
||||
u ^= (1 << i);
|
||||
|
||||
if (format_syndromes(u, s))
|
||||
return QUIRC_ERROR_FORMAT_ECC;
|
||||
|
||||
*f_ret = u;
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Decoder algorithm
|
||||
*/
|
||||
|
||||
struct datastream
|
||||
{
|
||||
uint8_t raw[QUIRC_MAX_PAYLOAD];
|
||||
int data_bits;
|
||||
int ptr;
|
||||
|
||||
uint8_t data[QUIRC_MAX_PAYLOAD];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
static inline int grid_bit(const struct quirc_code *code, int x, int y)
|
||||
{
|
||||
int p = y * code->size + x;
|
||||
|
||||
return (code->cell_bitmap[p >> 3] >> (p & 7)) & 1;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t read_format(const struct quirc_code *code,
|
||||
struct quirc_data *data, int which)
|
||||
{
|
||||
int i;
|
||||
uint16_t format = 0;
|
||||
uint16_t fdata;
|
||||
quirc_decode_error_t err;
|
||||
|
||||
if (which)
|
||||
{
|
||||
for (i = 0; i < 7; i++)
|
||||
format = (format << 1) |
|
||||
grid_bit(code, 8, code->size - 1 - i);
|
||||
for (i = 0; i < 8; i++)
|
||||
format = (format << 1) |
|
||||
grid_bit(code, code->size - 8 + i, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const int xs[15] = {
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 4, 3, 2, 1, 0};
|
||||
static const int ys[15] = {
|
||||
0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 8, 8, 8, 8, 8};
|
||||
|
||||
for (i = 14; i >= 0; i--)
|
||||
format = (format << 1) | grid_bit(code, xs[i], ys[i]);
|
||||
}
|
||||
|
||||
format ^= 0x5412;
|
||||
|
||||
err = correct_format(&format);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
fdata = format >> 10;
|
||||
data->ecc_level = fdata >> 3;
|
||||
data->mask = fdata & 7;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static int mask_bit(int mask, int i, int j)
|
||||
{
|
||||
switch (mask)
|
||||
{
|
||||
case 0:
|
||||
return !((i + j) % 2);
|
||||
case 1:
|
||||
return !(i % 2);
|
||||
case 2:
|
||||
return !(j % 3);
|
||||
case 3:
|
||||
return !((i + j) % 3);
|
||||
case 4:
|
||||
return !(((i / 2) + (j / 3)) % 2);
|
||||
case 5:
|
||||
return !((i * j) % 2 + (i * j) % 3);
|
||||
case 6:
|
||||
return !(((i * j) % 2 + (i * j) % 3) % 2);
|
||||
case 7:
|
||||
return !(((i * j) % 3 + (i + j) % 2) % 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reserved_cell(int version, int i, int j)
|
||||
{
|
||||
const struct quirc_version_info *ver = &quirc_version_db[version];
|
||||
int size = version * 4 + 17;
|
||||
int ai = -1, aj = -1, a;
|
||||
|
||||
/* Finder + format: top left */
|
||||
if (i < 9 && j < 9)
|
||||
return 1;
|
||||
|
||||
/* Finder + format: bottom left */
|
||||
if (i + 8 >= size && j < 9)
|
||||
return 1;
|
||||
|
||||
/* Finder + format: top right */
|
||||
if (i < 9 && j + 8 >= size)
|
||||
return 1;
|
||||
|
||||
/* Exclude timing patterns */
|
||||
if (i == 6 || j == 6)
|
||||
return 1;
|
||||
|
||||
/* Exclude version info, if it exists. Version info sits adjacent to
|
||||
* the top-right and bottom-left finders in three rows, bounded by
|
||||
* the timing pattern.
|
||||
*/
|
||||
if (version >= 7)
|
||||
{
|
||||
if (i < 6 && j + 11 >= size)
|
||||
return 1;
|
||||
if (i + 11 >= size && j < 6)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Exclude alignment patterns */
|
||||
for (a = 0; a < QUIRC_MAX_ALIGNMENT && ver->apat[a]; a++)
|
||||
{
|
||||
int p = ver->apat[a];
|
||||
|
||||
if (abs(p - i) < 3)
|
||||
ai = a;
|
||||
if (abs(p - j) < 3)
|
||||
aj = a;
|
||||
}
|
||||
|
||||
if (ai >= 0 && aj >= 0)
|
||||
{
|
||||
a--;
|
||||
if (ai > 0 && ai < a)
|
||||
return 1;
|
||||
if (aj > 0 && aj < a)
|
||||
return 1;
|
||||
if (aj == a && ai == a)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void read_bit(const struct quirc_code *code,
|
||||
struct quirc_data *data,
|
||||
struct datastream *ds, int i, int j)
|
||||
{
|
||||
int bitpos = ds->data_bits & 7;
|
||||
int bytepos = ds->data_bits >> 3;
|
||||
int v = grid_bit(code, j, i);
|
||||
|
||||
if (mask_bit(data->mask, i, j))
|
||||
v ^= 1;
|
||||
|
||||
if (v)
|
||||
ds->raw[bytepos] |= (0x80 >> bitpos);
|
||||
|
||||
ds->data_bits++;
|
||||
}
|
||||
|
||||
static void read_data(const struct quirc_code *code,
|
||||
struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int y = code->size - 1;
|
||||
int x = code->size - 1;
|
||||
int dir = -1;
|
||||
|
||||
while (x > 0)
|
||||
{
|
||||
if (x == 6)
|
||||
x--;
|
||||
|
||||
if (!reserved_cell(data->version, y, x))
|
||||
read_bit(code, data, ds, y, x);
|
||||
|
||||
if (!reserved_cell(data->version, y, x - 1))
|
||||
read_bit(code, data, ds, y, x - 1);
|
||||
|
||||
y += dir;
|
||||
if (y < 0 || y >= code->size)
|
||||
{
|
||||
dir = -dir;
|
||||
x -= 2;
|
||||
y += dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static quirc_decode_error_t codestream_ecc(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
const struct quirc_version_info *ver =
|
||||
&quirc_version_db[data->version];
|
||||
const struct quirc_rs_params *sb_ecc = &ver->ecc[data->ecc_level];
|
||||
struct quirc_rs_params lb_ecc;
|
||||
const int lb_count =
|
||||
(ver->data_bytes - sb_ecc->bs * sb_ecc->ns) / (sb_ecc->bs + 1);
|
||||
const int bc = lb_count + sb_ecc->ns;
|
||||
const int ecc_offset = sb_ecc->dw * bc + lb_count;
|
||||
int dst_offset = 0;
|
||||
int i;
|
||||
|
||||
memcpy(&lb_ecc, sb_ecc, sizeof(lb_ecc));
|
||||
lb_ecc.dw++;
|
||||
lb_ecc.bs++;
|
||||
|
||||
for (i = 0; i < bc; i++)
|
||||
{
|
||||
uint8_t *dst = ds->data + dst_offset;
|
||||
const struct quirc_rs_params *ecc =
|
||||
(i < sb_ecc->ns) ? sb_ecc : &lb_ecc;
|
||||
const int num_ec = ecc->bs - ecc->dw;
|
||||
quirc_decode_error_t err;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < ecc->dw; j++)
|
||||
dst[j] = ds->raw[j * bc + i];
|
||||
for (j = 0; j < num_ec; j++)
|
||||
dst[ecc->dw + j] = ds->raw[ecc_offset + j * bc + i];
|
||||
|
||||
err = correct_block(dst, ecc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dst_offset += ecc->dw;
|
||||
}
|
||||
|
||||
ds->data_bits = dst_offset * 8;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int bits_remaining(const struct datastream *ds)
|
||||
{
|
||||
return ds->data_bits - ds->ptr;
|
||||
}
|
||||
|
||||
static int take_bits(struct datastream *ds, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (len && (ds->ptr < ds->data_bits))
|
||||
{
|
||||
uint8_t b = ds->data[ds->ptr >> 3];
|
||||
int bitpos = ds->ptr & 7;
|
||||
|
||||
ret <<= 1;
|
||||
if ((b << bitpos) & 0x80)
|
||||
ret |= 1;
|
||||
|
||||
ds->ptr++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int numeric_tuple(struct quirc_data *data,
|
||||
struct datastream *ds,
|
||||
int bits, int digits)
|
||||
{
|
||||
int tuple;
|
||||
int i;
|
||||
|
||||
if (bits_remaining(ds) < bits)
|
||||
return -1;
|
||||
|
||||
tuple = take_bits(ds, bits);
|
||||
|
||||
for (i = digits - 1; i >= 0; i--)
|
||||
{
|
||||
data->payload[data->payload_len + i] = tuple % 10 + '0';
|
||||
tuple /= 10;
|
||||
}
|
||||
|
||||
data->payload_len += digits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_numeric(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 14;
|
||||
int count;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 10;
|
||||
else if (data->version < 27)
|
||||
bits = 12;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
|
||||
while (count >= 3)
|
||||
{
|
||||
if (numeric_tuple(data, ds, 10, 3) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 3;
|
||||
}
|
||||
|
||||
if (count >= 2)
|
||||
{
|
||||
if (numeric_tuple(data, ds, 7, 2) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
if (numeric_tuple(data, ds, 4, 1) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count--;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static int alpha_tuple(struct quirc_data *data,
|
||||
struct datastream *ds,
|
||||
int bits, int digits)
|
||||
{
|
||||
int tuple;
|
||||
int i;
|
||||
|
||||
if (bits_remaining(ds) < bits)
|
||||
return -1;
|
||||
|
||||
tuple = take_bits(ds, bits);
|
||||
|
||||
for (i = 0; i < digits; i++)
|
||||
{
|
||||
static const char *alpha_map =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
|
||||
|
||||
data->payload[data->payload_len + digits - i - 1] =
|
||||
alpha_map[tuple % 45];
|
||||
tuple /= 45;
|
||||
}
|
||||
|
||||
data->payload_len += digits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_alpha(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 13;
|
||||
int count;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 9;
|
||||
else if (data->version < 27)
|
||||
bits = 11;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
|
||||
while (count >= 2)
|
||||
{
|
||||
if (alpha_tuple(data, ds, 11, 2) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
if (alpha_tuple(data, ds, 6, 1) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count--;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_byte(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 16;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 8;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
if (bits_remaining(ds) < count * 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
data->payload[data->payload_len++] = take_bits(ds, 8);
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_kanji(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 12;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 8;
|
||||
else if (data->version < 27)
|
||||
bits = 10;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count * 2 + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
if (bits_remaining(ds) < count * 13)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
int d = take_bits(ds, 13);
|
||||
int msB = d / 0xc0;
|
||||
int lsB = d % 0xc0;
|
||||
int intermediate = (msB << 8) | lsB;
|
||||
uint16_t sjw;
|
||||
|
||||
if (intermediate + 0x8140 <= 0x9ffc)
|
||||
{
|
||||
/* bytes are in the range 0x8140 to 0x9FFC */
|
||||
sjw = intermediate + 0x8140;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bytes are in the range 0xE040 to 0xEBBF */
|
||||
sjw = intermediate + 0xc140;
|
||||
}
|
||||
|
||||
data->payload[data->payload_len++] = sjw >> 8;
|
||||
data->payload[data->payload_len++] = sjw & 0xff;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_eci(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
if (bits_remaining(ds) < 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = take_bits(ds, 8);
|
||||
|
||||
if ((data->eci & 0xc0) == 0x80)
|
||||
{
|
||||
if (bits_remaining(ds) < 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = (data->eci << 8) | take_bits(ds, 8);
|
||||
}
|
||||
else if ((data->eci & 0xe0) == 0xc0)
|
||||
{
|
||||
if (bits_remaining(ds) < 16)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = (data->eci << 16) | take_bits(ds, 16);
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_payload(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
while (bits_remaining(ds) >= 4)
|
||||
{
|
||||
quirc_decode_error_t err = QUIRC_SUCCESS;
|
||||
int type = take_bits(ds, 4);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case QUIRC_DATA_TYPE_NUMERIC:
|
||||
err = decode_numeric(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_ALPHA:
|
||||
err = decode_alpha(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_BYTE:
|
||||
err = decode_byte(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_KANJI:
|
||||
err = decode_kanji(data, ds);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
err = decode_eci(data, ds);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!(type & (type - 1)) && (type > data->data_type))
|
||||
data->data_type = type;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
/* Add nul terminator to all payloads */
|
||||
if (data->payload_len >= sizeof(data->payload))
|
||||
data->payload_len--;
|
||||
data->payload[data->payload_len] = 0;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
||||
struct quirc_data *data)
|
||||
{
|
||||
quirc_decode_error_t err;
|
||||
struct datastream *ds = ps_malloc(sizeof(struct datastream));
|
||||
|
||||
if ((code->size - 17) % 4)
|
||||
{
|
||||
free(ds);
|
||||
return QUIRC_ERROR_INVALID_GRID_SIZE;
|
||||
}
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
memset(ds, 0, sizeof(*ds));
|
||||
|
||||
data->version = (code->size - 17) / 4;
|
||||
|
||||
if (data->version < 1 ||
|
||||
data->version > QUIRC_MAX_VERSION)
|
||||
{
|
||||
free(ds);
|
||||
return QUIRC_ERROR_INVALID_VERSION;
|
||||
}
|
||||
|
||||
/* Read format information -- try both locations */
|
||||
err = read_format(code, data, 0);
|
||||
if (err)
|
||||
err = read_format(code, data, 1);
|
||||
if (err)
|
||||
{
|
||||
free(ds);
|
||||
return err;
|
||||
}
|
||||
|
||||
read_data(code, data, ds);
|
||||
err = codestream_ecc(data, ds);
|
||||
if (err)
|
||||
{
|
||||
free(ds);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = decode_payload(data, ds);
|
||||
if (err)
|
||||
{
|
||||
free(ds);
|
||||
return err;
|
||||
}
|
||||
|
||||
free(ds);
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
70
libraries/ESP32QRCodeReader_Page_original/fmath.h
Normal file
70
libraries/ESP32QRCodeReader_Page_original/fmath.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Fast approximate math functions.
|
||||
*
|
||||
*/
|
||||
#ifndef __FMATH_H
|
||||
#define __FMATH_H
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
static inline float fast_sqrtf(float x)
|
||||
{
|
||||
//return sqrtf(x);
|
||||
asm("fsqrt.s %0, %1"
|
||||
: "=f"(x)
|
||||
: "f"(x));
|
||||
return x;
|
||||
}
|
||||
static inline int fast_floorf(float x)
|
||||
{
|
||||
return (int)(x);
|
||||
}
|
||||
|
||||
static inline int fast_ceilf(float x)
|
||||
{
|
||||
return (int)(x + 0.9999f);
|
||||
}
|
||||
|
||||
static inline int fast_roundf(float x)
|
||||
{
|
||||
return (int)(x);
|
||||
}
|
||||
|
||||
static inline float fast_fabsf(float d)
|
||||
{
|
||||
return fabsf(d);
|
||||
}
|
||||
|
||||
extern int fast_floorf(float x);
|
||||
extern int fast_ceilf(float x);
|
||||
extern int fast_roundf(float x);
|
||||
extern float fast_atanf(float x);
|
||||
extern float fast_atan2f(float y, float x);
|
||||
extern float fast_expf(float x);
|
||||
extern float fast_cbrtf(float d);
|
||||
extern float fast_fabsf(float d);
|
||||
extern float fast_log(float x);
|
||||
extern float fast_log2(float x);
|
||||
extern float fast_powf(float a, float b);
|
||||
|
||||
/*#define fast_sqrtf(x) (sqrtf(x))
|
||||
#define fast_floorf(x) ((int)floorf(x))
|
||||
#define fast_ceilf(x) ((int)ceilf(x))
|
||||
#define fast_roundf(x) ((int)roundf(x))
|
||||
#define fast_atanf(x) (atanf(x))
|
||||
#define fast_atan2f(x,y) (atan2f((x),(y)))
|
||||
#define fast_expf(x) (expf(x))
|
||||
#define fast_cbrtf(x) (cbrtf(x))
|
||||
#define fast_fabsf(x) (fabsf(x))
|
||||
#define fast_log(x) (log(x))
|
||||
#define fast_log2(x) (log2(x))
|
||||
#define fast_powf(x,y) (powf((x),(y)))
|
||||
*/
|
||||
|
||||
extern const float cos_table[360];
|
||||
extern const float sin_table[360];
|
||||
#endif // __FMATH_H
|
1286
libraries/ESP32QRCodeReader_Page_original/identify.c
Normal file
1286
libraries/ESP32QRCodeReader_Page_original/identify.c
Normal file
File diff suppressed because it is too large
Load Diff
104
libraries/ESP32QRCodeReader_Page_original/quirc.c
Normal file
104
libraries/ESP32QRCodeReader_Page_original/quirc.c
Normal file
@ -0,0 +1,104 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "quirc_internal.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
const char *quirc_version(void)
|
||||
{
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
//static struct quirc _q;
|
||||
struct quirc *quirc_new(void)
|
||||
{
|
||||
struct quirc *q = ps_malloc(sizeof(*q));
|
||||
|
||||
if (!q)
|
||||
return NULL;
|
||||
|
||||
memset(q, 0, sizeof(*q));
|
||||
return q;
|
||||
}
|
||||
|
||||
void quirc_destroy(struct quirc *q)
|
||||
{
|
||||
if (q->image)
|
||||
if (q->image)
|
||||
free(q->image);
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
if (q->pixels)
|
||||
free(q->pixels);
|
||||
|
||||
if (q)
|
||||
free(q);
|
||||
}
|
||||
|
||||
//static quirc_pixel_t img_buf[320*240];
|
||||
int quirc_resize(struct quirc *q, int w, int h)
|
||||
{
|
||||
if (q->image)
|
||||
{
|
||||
free(q->image);
|
||||
}
|
||||
uint8_t *new_image = ps_malloc(w * h);
|
||||
|
||||
if (!new_image)
|
||||
return -1;
|
||||
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
{ //should gray, 1==1
|
||||
size_t new_size = w * h * sizeof(quirc_pixel_t);
|
||||
if (q->pixels)
|
||||
free(q->pixels);
|
||||
quirc_pixel_t *new_pixels = ps_malloc(new_size);
|
||||
if (!new_pixels)
|
||||
{
|
||||
free(new_image);
|
||||
return -1;
|
||||
}
|
||||
q->pixels = new_pixels;
|
||||
}
|
||||
q->image = new_image;
|
||||
q->w = w;
|
||||
q->h = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int quirc_count(const struct quirc *q)
|
||||
{
|
||||
return q->num_grids;
|
||||
}
|
||||
|
||||
static const char *const error_table[] = {
|
||||
[QUIRC_SUCCESS] = "Success",
|
||||
[QUIRC_ERROR_INVALID_GRID_SIZE] = "Invalid grid size",
|
||||
[QUIRC_ERROR_INVALID_VERSION] = "Invalid version",
|
||||
[QUIRC_ERROR_FORMAT_ECC] = "Format data ECC failure",
|
||||
[QUIRC_ERROR_DATA_ECC] = "ECC failure",
|
||||
[QUIRC_ERROR_UNKNOWN_DATA_TYPE] = "Unknown data type",
|
||||
[QUIRC_ERROR_DATA_OVERFLOW] = "Data overflow",
|
||||
[QUIRC_ERROR_DATA_UNDERFLOW] = "Data underflow"};
|
||||
|
||||
const char *quirc_strerror(quirc_decode_error_t err)
|
||||
{
|
||||
if (err >= 0 && err < sizeof(error_table) / sizeof(error_table[0]))
|
||||
return error_table[err];
|
||||
|
||||
return "Unknown error";
|
||||
}
|
178
libraries/ESP32QRCodeReader_Page_original/quirc.h
Normal file
178
libraries/ESP32QRCodeReader_Page_original/quirc.h
Normal file
@ -0,0 +1,178 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef QUIRC_H_
|
||||
#define QUIRC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct quirc;
|
||||
|
||||
/* Obtain the library version string. */
|
||||
const char *quirc_version(void);
|
||||
|
||||
/* Construct a new QR-code recognizer. This function will return NULL
|
||||
* if sufficient memory could not be allocated.
|
||||
*/
|
||||
struct quirc *quirc_new(void);
|
||||
|
||||
/* Destroy a QR-code recognizer. */
|
||||
void quirc_destroy(struct quirc *q);
|
||||
|
||||
/* Resize the QR-code recognizer. The size of an image must be
|
||||
* specified before codes can be analyzed.
|
||||
*
|
||||
* This function returns 0 on success, or -1 if sufficient memory could
|
||||
* not be allocated.
|
||||
*/
|
||||
int quirc_resize(struct quirc *q, int w, int h);
|
||||
|
||||
/* These functions are used to process images for QR-code recognition.
|
||||
* quirc_begin() must first be called to obtain access to a buffer into
|
||||
* which the input image should be placed. Optionally, the current
|
||||
* width and height may be returned.
|
||||
*
|
||||
* After filling the buffer, quirc_end() should be called to process
|
||||
* the image for QR-code recognition. The locations and content of each
|
||||
* code may be obtained using accessor functions described below.
|
||||
*/
|
||||
uint8_t *quirc_begin(struct quirc *q, int *w, int *h);
|
||||
void quirc_end(struct quirc *q);
|
||||
|
||||
/* This structure describes a location in the input image buffer. */
|
||||
struct quirc_point
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* This enum describes the various decoder errors which may occur. */
|
||||
typedef enum
|
||||
{
|
||||
QUIRC_SUCCESS = 0,
|
||||
QUIRC_ERROR_INVALID_GRID_SIZE,
|
||||
QUIRC_ERROR_INVALID_VERSION,
|
||||
QUIRC_ERROR_FORMAT_ECC,
|
||||
QUIRC_ERROR_DATA_ECC,
|
||||
QUIRC_ERROR_UNKNOWN_DATA_TYPE,
|
||||
QUIRC_ERROR_DATA_OVERFLOW,
|
||||
QUIRC_ERROR_DATA_UNDERFLOW
|
||||
} quirc_decode_error_t;
|
||||
|
||||
/* Return a string error message for an error code. */
|
||||
const char *quirc_strerror(quirc_decode_error_t err);
|
||||
|
||||
/* Limits on the maximum size of QR-codes and their content. */
|
||||
#define QUIRC_MAX_BITMAP 3917
|
||||
#define QUIRC_MAX_PAYLOAD 8896
|
||||
|
||||
/* QR-code ECC types. */
|
||||
#define QUIRC_ECC_LEVEL_M 0
|
||||
#define QUIRC_ECC_LEVEL_L 1
|
||||
#define QUIRC_ECC_LEVEL_H 2
|
||||
#define QUIRC_ECC_LEVEL_Q 3
|
||||
|
||||
/* QR-code data types. */
|
||||
#define QUIRC_DATA_TYPE_NUMERIC 1
|
||||
#define QUIRC_DATA_TYPE_ALPHA 2
|
||||
#define QUIRC_DATA_TYPE_BYTE 4
|
||||
#define QUIRC_DATA_TYPE_KANJI 8
|
||||
|
||||
/* Common character encodings */
|
||||
#define QUIRC_ECI_ISO_8859_1 1
|
||||
#define QUIRC_ECI_IBM437 2
|
||||
#define QUIRC_ECI_ISO_8859_2 4
|
||||
#define QUIRC_ECI_ISO_8859_3 5
|
||||
#define QUIRC_ECI_ISO_8859_4 6
|
||||
#define QUIRC_ECI_ISO_8859_5 7
|
||||
#define QUIRC_ECI_ISO_8859_6 8
|
||||
#define QUIRC_ECI_ISO_8859_7 9
|
||||
#define QUIRC_ECI_ISO_8859_8 10
|
||||
#define QUIRC_ECI_ISO_8859_9 11
|
||||
#define QUIRC_ECI_WINDOWS_874 13
|
||||
#define QUIRC_ECI_ISO_8859_13 15
|
||||
#define QUIRC_ECI_ISO_8859_15 17
|
||||
#define QUIRC_ECI_SHIFT_JIS 20
|
||||
#define QUIRC_ECI_UTF_8 26
|
||||
|
||||
/* This structure is used to return information about detected QR codes
|
||||
* in the input image.
|
||||
*/
|
||||
struct quirc_code
|
||||
{
|
||||
/* The four corners of the QR-code, from top left, clockwise */
|
||||
struct quirc_point corners[4];
|
||||
|
||||
/* The number of cells across in the QR-code. The cell bitmap
|
||||
* is a bitmask giving the actual values of cells. If the cell
|
||||
* at (x, y) is black, then the following bit is set:
|
||||
*
|
||||
* cell_bitmap[i >> 3] & (1 << (i & 7))
|
||||
*
|
||||
* where i = (y * size) + x.
|
||||
*/
|
||||
int size;
|
||||
uint8_t cell_bitmap[QUIRC_MAX_BITMAP];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* This structure holds the decoded QR-code data */
|
||||
struct quirc_data
|
||||
{
|
||||
/* Various parameters of the QR-code. These can mostly be
|
||||
* ignored if you only care about the data.
|
||||
*/
|
||||
int version;
|
||||
int ecc_level;
|
||||
int mask;
|
||||
|
||||
/* This field is the highest-valued data type found in the QR
|
||||
* code.
|
||||
*/
|
||||
int data_type;
|
||||
|
||||
/* Data payload. For the Kanji datatype, payload is encoded as
|
||||
* Shift-JIS. For all other datatypes, payload is ASCII text.
|
||||
*/
|
||||
uint8_t payload[QUIRC_MAX_PAYLOAD];
|
||||
int payload_len;
|
||||
|
||||
/* ECI assignment number */
|
||||
uint32_t eci;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* Return the number of QR-codes identified in the last processed
|
||||
* image.
|
||||
*/
|
||||
int quirc_count(const struct quirc *q);
|
||||
|
||||
/* Extract the QR-code specified by the given index. */
|
||||
void quirc_extract(const struct quirc *q, int index,
|
||||
struct quirc_code *code);
|
||||
|
||||
/* Decode a QR-code, returning the payload data. */
|
||||
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
||||
struct quirc_data *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
121
libraries/ESP32QRCodeReader_Page_original/quirc_internal.h
Normal file
121
libraries/ESP32QRCodeReader_Page_original/quirc_internal.h
Normal file
@ -0,0 +1,121 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef QUIRC_INTERNAL_H_
|
||||
#define QUIRC_INTERNAL_H_
|
||||
|
||||
#include "quirc.h"
|
||||
|
||||
#define QUIRC_PIXEL_WHITE 0
|
||||
#define QUIRC_PIXEL_BLACK 1
|
||||
#define QUIRC_PIXEL_REGION 2
|
||||
|
||||
#ifndef QUIRC_MAX_REGIONS
|
||||
#define QUIRC_MAX_REGIONS 254
|
||||
#endif
|
||||
|
||||
#define QUIRC_MAX_CAPSTONES 32
|
||||
#define QUIRC_MAX_GRIDS 8
|
||||
|
||||
#define QUIRC_PERSPECTIVE_PARAMS 8
|
||||
|
||||
#if QUIRC_MAX_REGIONS < UINT8_MAX
|
||||
typedef uint8_t quirc_pixel_t;
|
||||
#elif QUIRC_MAX_REGIONS < UINT16_MAX
|
||||
typedef uint16_t quirc_pixel_t;
|
||||
#else
|
||||
#error "QUIRC_MAX_REGIONS > 65534 is not supported"
|
||||
#endif
|
||||
|
||||
struct quirc_region
|
||||
{
|
||||
struct quirc_point seed;
|
||||
int count;
|
||||
int capstone;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_capstone
|
||||
{
|
||||
int ring;
|
||||
int stone;
|
||||
|
||||
struct quirc_point corners[4];
|
||||
struct quirc_point center;
|
||||
float c[QUIRC_PERSPECTIVE_PARAMS];
|
||||
|
||||
int qr_grid;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_grid
|
||||
{
|
||||
/* Capstone indices */
|
||||
int caps[3];
|
||||
|
||||
/* Alignment pattern region and corner */
|
||||
int align_region;
|
||||
struct quirc_point align;
|
||||
|
||||
/* Timing pattern endpoints */
|
||||
struct quirc_point tpep[3];
|
||||
int hscan;
|
||||
int vscan;
|
||||
|
||||
/* Grid size and perspective transform */
|
||||
int grid_size;
|
||||
float c[QUIRC_PERSPECTIVE_PARAMS];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc
|
||||
{
|
||||
uint8_t *image;
|
||||
quirc_pixel_t *pixels;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
int num_regions;
|
||||
struct quirc_region regions[QUIRC_MAX_REGIONS];
|
||||
|
||||
int num_capstones;
|
||||
struct quirc_capstone capstones[QUIRC_MAX_CAPSTONES];
|
||||
|
||||
int num_grids;
|
||||
struct quirc_grid grids[QUIRC_MAX_GRIDS];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/************************************************************************
|
||||
* QR-code version information database
|
||||
*/
|
||||
|
||||
#define QUIRC_MAX_VERSION 40
|
||||
#define QUIRC_MAX_ALIGNMENT 7
|
||||
|
||||
struct quirc_rs_params
|
||||
{
|
||||
uint8_t bs; /* Small block size */
|
||||
uint8_t dw; /* Small data words */
|
||||
uint8_t ns; /* Number of small blocks */
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_version_info
|
||||
{
|
||||
uint16_t data_bytes;
|
||||
uint8_t apat[QUIRC_MAX_ALIGNMENT];
|
||||
struct quirc_rs_params ecc[4];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
extern const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1];
|
||||
|
||||
#endif
|
184
libraries/ESP32QRCodeReader_Page_original/version_db.c
Normal file
184
libraries/ESP32QRCodeReader_Page_original/version_db.c
Normal file
@ -0,0 +1,184 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "quirc_internal.h"
|
||||
|
||||
const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = {
|
||||
{0},
|
||||
{/* Version 1 */
|
||||
.data_bytes = 26,
|
||||
.apat = {0},
|
||||
.ecc = {
|
||||
{.bs = 26, .dw = 16, .ns = 1},
|
||||
{.bs = 26, .dw = 19, .ns = 1},
|
||||
{.bs = 26, .dw = 9, .ns = 1},
|
||||
{.bs = 26, .dw = 13, .ns = 1}}},
|
||||
{/* Version 2 */
|
||||
.data_bytes = 44,
|
||||
.apat = {6, 18, 0},
|
||||
.ecc = {{.bs = 44, .dw = 28, .ns = 1}, {.bs = 44, .dw = 34, .ns = 1}, {.bs = 44, .dw = 16, .ns = 1}, {.bs = 44, .dw = 22, .ns = 1}}},
|
||||
{/* Version 3 */
|
||||
.data_bytes = 70,
|
||||
.apat = {6, 22, 0},
|
||||
.ecc = {{.bs = 70, .dw = 44, .ns = 1}, {.bs = 70, .dw = 55, .ns = 1}, {.bs = 35, .dw = 13, .ns = 2}, {.bs = 35, .dw = 17, .ns = 2}}},
|
||||
{/* Version 4 */
|
||||
.data_bytes = 100,
|
||||
.apat = {6, 26, 0},
|
||||
.ecc = {{.bs = 50, .dw = 32, .ns = 2}, {.bs = 100, .dw = 80, .ns = 1}, {.bs = 25, .dw = 9, .ns = 4}, {.bs = 50, .dw = 24, .ns = 2}}},
|
||||
{/* Version 5 */
|
||||
.data_bytes = 134,
|
||||
.apat = {6, 30, 0},
|
||||
.ecc = {{.bs = 67, .dw = 43, .ns = 2}, {.bs = 134, .dw = 108, .ns = 1}, {.bs = 33, .dw = 11, .ns = 2}, {.bs = 33, .dw = 15, .ns = 2}}},
|
||||
{/* Version 6 */
|
||||
.data_bytes = 172,
|
||||
.apat = {6, 34, 0},
|
||||
.ecc = {{.bs = 43, .dw = 27, .ns = 4}, {.bs = 86, .dw = 68, .ns = 2}, {.bs = 43, .dw = 15, .ns = 4}, {.bs = 43, .dw = 19, .ns = 4}}},
|
||||
{/* Version 7 */
|
||||
.data_bytes = 196,
|
||||
.apat = {6, 22, 38, 0},
|
||||
.ecc = {{.bs = 49, .dw = 31, .ns = 4}, {.bs = 98, .dw = 78, .ns = 2}, {.bs = 39, .dw = 13, .ns = 4}, {.bs = 32, .dw = 14, .ns = 2}}},
|
||||
{/* Version 8 */
|
||||
.data_bytes = 242,
|
||||
.apat = {6, 24, 42, 0},
|
||||
.ecc = {{.bs = 60, .dw = 38, .ns = 2}, {.bs = 121, .dw = 97, .ns = 2}, {.bs = 40, .dw = 14, .ns = 4}, {.bs = 40, .dw = 18, .ns = 4}}},
|
||||
{/* Version 9 */
|
||||
.data_bytes = 292,
|
||||
.apat = {6, 26, 46, 0},
|
||||
.ecc = {{.bs = 58, .dw = 36, .ns = 3}, {.bs = 146, .dw = 116, .ns = 2}, {.bs = 36, .dw = 12, .ns = 4}, {.bs = 36, .dw = 16, .ns = 4}}},
|
||||
{/* Version 10 */
|
||||
.data_bytes = 346,
|
||||
.apat = {6, 28, 50, 0},
|
||||
.ecc = {{.bs = 69, .dw = 43, .ns = 4}, {.bs = 86, .dw = 68, .ns = 2}, {.bs = 43, .dw = 15, .ns = 6}, {.bs = 43, .dw = 19, .ns = 6}}},
|
||||
{/* Version 11 */
|
||||
.data_bytes = 404,
|
||||
.apat = {6, 30, 54, 0},
|
||||
.ecc = {{.bs = 80, .dw = 50, .ns = 1}, {.bs = 101, .dw = 81, .ns = 4}, {.bs = 36, .dw = 12, .ns = 3}, {.bs = 50, .dw = 22, .ns = 4}}},
|
||||
{/* Version 12 */
|
||||
.data_bytes = 466,
|
||||
.apat = {6, 32, 58, 0},
|
||||
.ecc = {{.bs = 58, .dw = 36, .ns = 6}, {.bs = 116, .dw = 92, .ns = 2}, {.bs = 42, .dw = 14, .ns = 7}, {.bs = 46, .dw = 20, .ns = 4}}},
|
||||
{/* Version 13 */
|
||||
.data_bytes = 532,
|
||||
.apat = {6, 34, 62, 0},
|
||||
.ecc = {{.bs = 59, .dw = 37, .ns = 8}, {.bs = 133, .dw = 107, .ns = 4}, {.bs = 33, .dw = 11, .ns = 12}, {.bs = 44, .dw = 20, .ns = 8}}},
|
||||
{/* Version 14 */
|
||||
.data_bytes = 581,
|
||||
.apat = {6, 26, 46, 66, 0},
|
||||
.ecc = {{.bs = 64, .dw = 40, .ns = 4}, {.bs = 145, .dw = 115, .ns = 3}, {.bs = 36, .dw = 12, .ns = 11}, {.bs = 36, .dw = 16, .ns = 11}}},
|
||||
{/* Version 15 */
|
||||
.data_bytes = 655,
|
||||
.apat = {6, 26, 48, 70, 0},
|
||||
.ecc = {{.bs = 65, .dw = 41, .ns = 5}, {.bs = 109, .dw = 87, .ns = 5}, {.bs = 36, .dw = 12, .ns = 11}, {.bs = 54, .dw = 24, .ns = 5}}},
|
||||
{/* Version 16 */
|
||||
.data_bytes = 733,
|
||||
.apat = {6, 26, 50, 74, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 7}, {.bs = 122, .dw = 98, .ns = 5}, {.bs = 45, .dw = 15, .ns = 3}, {.bs = 43, .dw = 19, .ns = 15}}},
|
||||
{/* Version 17 */
|
||||
.data_bytes = 815,
|
||||
.apat = {6, 30, 54, 78, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 10}, {.bs = 135, .dw = 107, .ns = 1}, {.bs = 42, .dw = 14, .ns = 2}, {.bs = 50, .dw = 22, .ns = 1}}},
|
||||
{/* Version 18 */
|
||||
.data_bytes = 901,
|
||||
.apat = {6, 30, 56, 82, 0},
|
||||
.ecc = {{.bs = 69, .dw = 43, .ns = 9}, {.bs = 150, .dw = 120, .ns = 5}, {.bs = 42, .dw = 14, .ns = 2}, {.bs = 50, .dw = 22, .ns = 17}}},
|
||||
{/* Version 19 */
|
||||
.data_bytes = 991,
|
||||
.apat = {6, 30, 58, 86, 0},
|
||||
.ecc = {{.bs = 70, .dw = 44, .ns = 3}, {.bs = 141, .dw = 113, .ns = 3}, {.bs = 39, .dw = 13, .ns = 9}, {.bs = 47, .dw = 21, .ns = 17}}},
|
||||
{/* Version 20 */
|
||||
.data_bytes = 1085,
|
||||
.apat = {6, 34, 62, 90, 0},
|
||||
.ecc = {{.bs = 67, .dw = 41, .ns = 3}, {.bs = 135, .dw = 107, .ns = 3}, {.bs = 43, .dw = 15, .ns = 15}, {.bs = 54, .dw = 24, .ns = 15}}},
|
||||
{/* Version 21 */
|
||||
.data_bytes = 1156,
|
||||
.apat = {6, 28, 50, 72, 92, 0},
|
||||
.ecc = {{.bs = 68, .dw = 42, .ns = 17}, {.bs = 144, .dw = 116, .ns = 4}, {.bs = 46, .dw = 16, .ns = 19}, {.bs = 50, .dw = 22, .ns = 17}}},
|
||||
{/* Version 22 */
|
||||
.data_bytes = 1258,
|
||||
.apat = {6, 26, 50, 74, 98, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 17}, {.bs = 139, .dw = 111, .ns = 2}, {.bs = 37, .dw = 13, .ns = 34}, {.bs = 54, .dw = 24, .ns = 7}}},
|
||||
{/* Version 23 */
|
||||
.data_bytes = 1364,
|
||||
.apat = {6, 30, 54, 78, 102, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 4}, {.bs = 151, .dw = 121, .ns = 4}, {.bs = 45, .dw = 15, .ns = 16}, {.bs = 54, .dw = 24, .ns = 11}}},
|
||||
{/* Version 24 */
|
||||
.data_bytes = 1474,
|
||||
.apat = {6, 28, 54, 80, 106, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 6}, {.bs = 147, .dw = 117, .ns = 6}, {.bs = 46, .dw = 16, .ns = 30}, {.bs = 54, .dw = 24, .ns = 11}}},
|
||||
{/* Version 25 */
|
||||
.data_bytes = 1588,
|
||||
.apat = {6, 32, 58, 84, 110, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 8}, {.bs = 132, .dw = 106, .ns = 8}, {.bs = 45, .dw = 15, .ns = 22}, {.bs = 54, .dw = 24, .ns = 7}}},
|
||||
{/* Version 26 */
|
||||
.data_bytes = 1706,
|
||||
.apat = {6, 30, 58, 86, 114, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 19}, {.bs = 142, .dw = 114, .ns = 10}, {.bs = 46, .dw = 16, .ns = 33}, {.bs = 50, .dw = 22, .ns = 28}}},
|
||||
{/* Version 27 */
|
||||
.data_bytes = 1828,
|
||||
.apat = {6, 34, 62, 90, 118, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 22}, {.bs = 152, .dw = 122, .ns = 8}, {.bs = 45, .dw = 15, .ns = 12}, {.bs = 53, .dw = 23, .ns = 8}}},
|
||||
{/* Version 28 */
|
||||
.data_bytes = 1921,
|
||||
.apat = {6, 26, 50, 74, 98, 122, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 3}, {.bs = 147, .dw = 117, .ns = 3}, {.bs = 45, .dw = 15, .ns = 11}, {.bs = 54, .dw = 24, .ns = 4}}},
|
||||
{/* Version 29 */
|
||||
.data_bytes = 2051,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 21}, {.bs = 146, .dw = 116, .ns = 7}, {.bs = 45, .dw = 15, .ns = 19}, {.bs = 53, .dw = 23, .ns = 1}}},
|
||||
{/* Version 30 */
|
||||
.data_bytes = 2185,
|
||||
.apat = {6, 26, 52, 78, 104, 130, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 19}, {.bs = 145, .dw = 115, .ns = 5}, {.bs = 45, .dw = 15, .ns = 23}, {.bs = 54, .dw = 24, .ns = 15}}},
|
||||
{/* Version 31 */
|
||||
.data_bytes = 2323,
|
||||
.apat = {6, 30, 56, 82, 108, 134, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 2}, {.bs = 145, .dw = 115, .ns = 13}, {.bs = 45, .dw = 15, .ns = 23}, {.bs = 54, .dw = 24, .ns = 42}}},
|
||||
{/* Version 32 */
|
||||
.data_bytes = 2465,
|
||||
.apat = {6, 34, 60, 86, 112, 138, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 10}, {.bs = 145, .dw = 115, .ns = 17}, {.bs = 45, .dw = 15, .ns = 19}, {.bs = 54, .dw = 24, .ns = 10}}},
|
||||
{/* Version 33 */
|
||||
.data_bytes = 2611,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 14}, {.bs = 145, .dw = 115, .ns = 17}, {.bs = 45, .dw = 15, .ns = 11}, {.bs = 54, .dw = 24, .ns = 29}}},
|
||||
{/* Version 34 */
|
||||
.data_bytes = 2761,
|
||||
.apat = {6, 34, 62, 90, 118, 146, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 14}, {.bs = 145, .dw = 115, .ns = 13}, {.bs = 46, .dw = 16, .ns = 59}, {.bs = 54, .dw = 24, .ns = 44}}},
|
||||
{/* Version 35 */
|
||||
.data_bytes = 2876,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 150},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 12}, {.bs = 151, .dw = 121, .ns = 12}, {.bs = 45, .dw = 15, .ns = 22}, {.bs = 54, .dw = 24, .ns = 39}}},
|
||||
{/* Version 36 */
|
||||
.data_bytes = 3034,
|
||||
.apat = {6, 24, 50, 76, 102, 128, 154},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 6}, {.bs = 151, .dw = 121, .ns = 6}, {.bs = 45, .dw = 15, .ns = 2}, {.bs = 54, .dw = 24, .ns = 46}}},
|
||||
{/* Version 37 */
|
||||
.data_bytes = 3196,
|
||||
.apat = {6, 28, 54, 80, 106, 132, 158},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 29}, {.bs = 152, .dw = 122, .ns = 17}, {.bs = 45, .dw = 15, .ns = 24}, {.bs = 54, .dw = 24, .ns = 49}}},
|
||||
{/* Version 38 */
|
||||
.data_bytes = 3362,
|
||||
.apat = {6, 32, 58, 84, 110, 136, 162},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 13}, {.bs = 152, .dw = 122, .ns = 4}, {.bs = 45, .dw = 15, .ns = 42}, {.bs = 54, .dw = 24, .ns = 48}}},
|
||||
{/* Version 39 */
|
||||
.data_bytes = 3532,
|
||||
.apat = {6, 26, 54, 82, 110, 138, 166},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 40}, {.bs = 147, .dw = 117, .ns = 20}, {.bs = 45, .dw = 15, .ns = 10}, {.bs = 54, .dw = 24, .ns = 43}}},
|
||||
{/* Version 40 */
|
||||
.data_bytes = 3706,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 170},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 18}, {.bs = 148, .dw = 118, .ns = 19}, {.bs = 45, .dw = 15, .ns = 20}, {.bs = 54, .dw = 24, .ns = 34}}}};
|
54
libraries/MySQL_MariaDB_Generic-1.7.2/CONTRIBUTING.md
Normal file
54
libraries/MySQL_MariaDB_Generic-1.7.2/CONTRIBUTING.md
Normal file
@ -0,0 +1,54 @@
|
||||
## Contributing to MySQL_MariaDB_Generic
|
||||
|
||||
### Reporting Bugs
|
||||
|
||||
Please report bugs in MySQL_MariaDB_Generic if you find them.
|
||||
|
||||
However, before reporting a bug please check through the following:
|
||||
|
||||
* [Existing Open Issues](https://github.com/khoih-prog/MySQL_MariaDB_Generic/issues) - someone might have already encountered this.
|
||||
|
||||
If you don't find anything, please [open a new issue](https://github.com/khoih-prog/MySQL_MariaDB_Generic/issues/new).
|
||||
|
||||
### How to submit a bug report
|
||||
|
||||
Please ensure to specify the following:
|
||||
|
||||
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
|
||||
* Board Core Version (e.g. Arduino SAMDUE core v1.6.12, ESP32 core v2.0.2, ESP8266 core v3.0.2, ArduinoCore-mbed v3.0.1, etc.)
|
||||
* Contextual information (e.g. what you were trying to achieve)
|
||||
* Simplest possible steps to reproduce
|
||||
* Anything that might be relevant in your opinion, such as:
|
||||
* Operating system (Windows, Ubuntu, etc.) and the output of `uname -a`
|
||||
* Network configuration
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
Arduino IDE version: 1.8.19
|
||||
MBED RASPBERRY_PI_PICO board
|
||||
ArduinoCore-mbed v3.0.1
|
||||
OS: Ubuntu 20.04 LTS
|
||||
Linux xy-Inspiron-3593 5.13.0-39-generic #44~20.04.1-Ubuntu SMP Thu Mar 24 16:43:35 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
|
||||
|
||||
Context:
|
||||
I encountered a crash while trying to use the Timer Interrupt.
|
||||
|
||||
Steps to reproduce:
|
||||
1. ...
|
||||
2. ...
|
||||
3. ...
|
||||
4. ...
|
||||
```
|
||||
|
||||
### Sending Feature Requests
|
||||
|
||||
Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful.
|
||||
|
||||
There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/MySQL_MariaDB_Generic/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them.
|
||||
|
||||
### Sending Pull Requests
|
||||
|
||||
Pull Requests with changes and fixes are also welcome!
|
||||
|
22
libraries/MySQL_MariaDB_Generic-1.7.2/LICENSE
Normal file
22
libraries/MySQL_MariaDB_Generic-1.7.2/LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Khoi Hoang <khoih58@gmail.com>
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
@ -0,0 +1,320 @@
|
||||
/****************************************************************************************************************************
|
||||
Ethernet.cpp
|
||||
|
||||
EthernetWebServer is a library for the Ethernet shields to run WebServer
|
||||
|
||||
Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer
|
||||
Licensed under MIT license
|
||||
Version: 1.0.9
|
||||
|
||||
Copyright 2018 Paul Stoffregen
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries
|
||||
1.0.1 K Hoang 20/02/2020 Add support to lambda functions
|
||||
1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60
|
||||
1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards
|
||||
1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards
|
||||
1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense,
|
||||
Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc.
|
||||
More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge
|
||||
1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards
|
||||
1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards
|
||||
1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards.
|
||||
1.0.9 K Hoang 15/05/2020 Add EthernetWrapper.h for easier W5x00 support as well as more Ethernet libs in the future.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "Ethernet.h"
|
||||
#include "utility/w5100.h"
|
||||
#include "Dhcp.h"
|
||||
|
||||
#define ETHERNET_DEBUG 1
|
||||
|
||||
|
||||
IPAddress EthernetClass::_dnsServerAddress;
|
||||
DhcpClass* EthernetClass::_dhcp = NULL;
|
||||
|
||||
// KH
|
||||
void EthernetClass::setRstPin(uint8_t pinRST)
|
||||
{
|
||||
_pinRST = pinRST;
|
||||
pinMode(_pinRST, OUTPUT);
|
||||
digitalWrite(_pinRST, HIGH);
|
||||
}
|
||||
void EthernetClass::setCsPin(uint8_t pinCS)
|
||||
{
|
||||
_pinCS = pinCS;
|
||||
W5100.setSS(pinCS);
|
||||
|
||||
#if ( ETHERNET_DEBUG > 0 )
|
||||
Serial.print("Input pinCS = ");
|
||||
Serial.println(pinCS);
|
||||
Serial.print("_pinCS = ");
|
||||
Serial.println(_pinCS);
|
||||
#endif
|
||||
}
|
||||
|
||||
void EthernetClass::initMaxSockNum(uint8_t maxSockNum)
|
||||
{
|
||||
_maxSockNum = maxSockNum;
|
||||
}
|
||||
|
||||
uint8_t EthernetClass::softreset()
|
||||
{
|
||||
return W5100.softReset();
|
||||
}
|
||||
|
||||
void EthernetClass::hardreset()
|
||||
{
|
||||
if(_pinRST != 0)
|
||||
{
|
||||
digitalWrite(_pinRST, LOW);
|
||||
delay(1);
|
||||
digitalWrite(_pinRST, HIGH);
|
||||
delay(150);
|
||||
}
|
||||
}
|
||||
|
||||
int EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)
|
||||
{
|
||||
DhcpClass s_dhcp;
|
||||
_dhcp = &s_dhcp;
|
||||
|
||||
#if ( ETHERNET_DEBUG > 0 )
|
||||
Serial.print("_pinCS = ");
|
||||
Serial.print(_pinCS);
|
||||
#endif
|
||||
|
||||
// Initialise the basic info
|
||||
if (W5100.init() == 0)
|
||||
return 0;
|
||||
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setMACAddress(mac);
|
||||
W5100.setIPAddress(IPAddress(0,0,0,0).raw_address());
|
||||
SPI.endTransaction();
|
||||
|
||||
// Now try to get our config info from a DHCP server
|
||||
int ret = _dhcp->beginWithDHCP(mac, timeout, responseTimeout);
|
||||
if (ret == 1)
|
||||
{
|
||||
// We've successfully found a DHCP server and got our configuration
|
||||
// info, so set things accordingly
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
SPI.endTransaction();
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
socketPortRand(micros());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac, IPAddress ip)
|
||||
{
|
||||
// Assume the DNS server will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress dns = ip;
|
||||
dns[3] = 1;
|
||||
begin(mac, ip, dns);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns)
|
||||
{
|
||||
// Assume the gateway will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress gateway = ip;
|
||||
gateway[3] = 1;
|
||||
begin(mac, ip, dns, gateway);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway)
|
||||
{
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
begin(mac, ip, dns, gateway, subnet);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)
|
||||
{
|
||||
// Initialise the basic info
|
||||
if (W5100.init() == 0)
|
||||
return;
|
||||
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setMACAddress(mac);
|
||||
|
||||
#if ( defined(ESP8266) || defined(ESP32) )
|
||||
W5100.setIPAddress(ip.raw_address());
|
||||
W5100.setGatewayIp(gateway.raw_address());
|
||||
W5100.setSubnetMask(subnet.raw_address());
|
||||
#elif (ARDUINO > 106 || TEENSYDUINO > 121)
|
||||
W5100.setIPAddress(ip._address.bytes);
|
||||
W5100.setGatewayIp(gateway._address.bytes);
|
||||
W5100.setSubnetMask(subnet._address.bytes);
|
||||
#else
|
||||
W5100.setIPAddress(ip._address);
|
||||
W5100.setGatewayIp(gateway._address);
|
||||
W5100.setSubnetMask(subnet._address);
|
||||
#endif
|
||||
|
||||
SPI.endTransaction();
|
||||
_dnsServerAddress = dns;
|
||||
}
|
||||
|
||||
void EthernetClass::init(uint8_t sspin)
|
||||
{
|
||||
W5100.setSS(sspin);
|
||||
}
|
||||
|
||||
EthernetLinkStatus EthernetClass::linkStatus()
|
||||
{
|
||||
switch (W5100.getLinkStatus()) {
|
||||
case UNKNOWN: return Unknown;
|
||||
case LINK_ON: return LinkON;
|
||||
case LINK_OFF: return LinkOFF;
|
||||
default: return Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
EthernetHardwareStatus EthernetClass::hardwareStatus()
|
||||
{
|
||||
switch (W5100.getChip()) {
|
||||
case 51: return EthernetW5100;
|
||||
case 52: return EthernetW5200;
|
||||
case 55: return EthernetW5500;
|
||||
default: return EthernetNoHardware;
|
||||
}
|
||||
}
|
||||
|
||||
int EthernetClass::maintain()
|
||||
{
|
||||
int rc = DHCP_CHECK_NONE;
|
||||
if (_dhcp != NULL) {
|
||||
// we have a pointer to dhcp, use it
|
||||
rc = _dhcp->checkLease();
|
||||
switch (rc)
|
||||
{
|
||||
case DHCP_CHECK_NONE:
|
||||
//nothing done
|
||||
break;
|
||||
case DHCP_CHECK_RENEW_OK:
|
||||
case DHCP_CHECK_REBIND_OK:
|
||||
//we might have got a new IP.
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
SPI.endTransaction();
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
break;
|
||||
default:
|
||||
//this is actually an error, it will retry though
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void EthernetClass::MACAddress(uint8_t *mac_address)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.getMACAddress(mac_address);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::localIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.getIPAddress(ret.raw_address());
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::subnetMask()
|
||||
{
|
||||
IPAddress ret;
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.getSubnetMask(ret.raw_address());
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::gatewayIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.getGatewayIp(ret.raw_address());
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EthernetClass::setMACAddress(const uint8_t *mac_address)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setMACAddress(mac_address);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void EthernetClass::setLocalIP(const IPAddress local_ip)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
IPAddress ip = local_ip;
|
||||
W5100.setIPAddress(ip.raw_address());
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void EthernetClass::setSubnetMask(const IPAddress subnet)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
IPAddress ip = subnet;
|
||||
W5100.setSubnetMask(ip.raw_address());
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void EthernetClass::setGatewayIP(const IPAddress gateway)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
IPAddress ip = gateway;
|
||||
W5100.setGatewayIp(ip.raw_address());
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void EthernetClass::setRetransmissionTimeout(uint16_t milliseconds)
|
||||
{
|
||||
if (milliseconds > 6553) milliseconds = 6553;
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setRetransmissionTime(milliseconds * 10);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void EthernetClass::setRetransmissionCount(uint8_t num)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setRetransmissionCount(num);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
EthernetClass Ethernet;
|
@ -0,0 +1,366 @@
|
||||
/****************************************************************************************************************************
|
||||
Ethernet.h
|
||||
|
||||
EthernetWebServer is a library for the Ethernet shields to run WebServer
|
||||
|
||||
Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer
|
||||
Licensed under MIT license
|
||||
Version: 1.0.9
|
||||
|
||||
Copyright 2018 Paul Stoffregen
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries
|
||||
1.0.1 K Hoang 20/02/2020 Add support to lambda functions
|
||||
1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60
|
||||
1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards
|
||||
1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards
|
||||
1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense,
|
||||
Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc.
|
||||
More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge
|
||||
1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards
|
||||
1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards
|
||||
1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards.
|
||||
1.0.9 K Hoang 15/05/2020 Add EthernetWrapper.h for easier W5x00 support as well as more Ethernet libs in the future.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#ifndef ethernet_h_
|
||||
#define ethernet_h_
|
||||
|
||||
// All symbols exposed to Arduino sketches are contained in this header file
|
||||
//
|
||||
// Older versions had much of this stuff in EthernetClient.h, EthernetServer.h,
|
||||
// and socket.h. Including headers in different order could cause trouble, so
|
||||
// these "friend" classes are now defined in the same header file. socket.h
|
||||
// was removed to avoid possible conflict with the C library header files.
|
||||
|
||||
|
||||
// Configure the maximum number of sockets to support. W5100 chips can have
|
||||
// up to 4 sockets. W5200 & W5500 can have up to 8 sockets. Several bytes
|
||||
// of RAM are used for each socket. Reducing the maximum can save RAM, but
|
||||
// you are limited to fewer simultaneous connections.
|
||||
#if defined(RAMEND) && defined(RAMSTART) && ((RAMEND - RAMSTART) <= 2048)
|
||||
#define MAX_SOCK_NUM 2 //Reduce MAX_SOCK_NUM to 2 from 4, to increase buffer from 2k to 4K
|
||||
#else
|
||||
#define MAX_SOCK_NUM 4 //Reduce MAX_SOCK_NUM to 4 from 8, to increase buffer from 2k to 4K
|
||||
#endif
|
||||
|
||||
// By default, each socket uses 2K buffers inside the Wiznet chip. If
|
||||
// MAX_SOCK_NUM is set to fewer than the chip's maximum, uncommenting
|
||||
// this will use larger buffers within the Wiznet chip. Large buffers
|
||||
// can really help with UDP protocols like Artnet. In theory larger
|
||||
// buffers should allow faster TCP over high-latency links, but this
|
||||
// does not always seem to work in practice (maybe Wiznet bugs?)
|
||||
//
|
||||
//KH, to increase buffer size for W5x00 to min 4K
|
||||
#define ETHERNET_LARGE_BUFFERS
|
||||
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "Client.h"
|
||||
#include "Server.h"
|
||||
#include "Udp.h"
|
||||
|
||||
enum EthernetLinkStatus {
|
||||
Unknown,
|
||||
LinkON,
|
||||
LinkOFF
|
||||
};
|
||||
|
||||
enum EthernetHardwareStatus {
|
||||
EthernetNoHardware,
|
||||
EthernetW5100,
|
||||
EthernetW5200,
|
||||
EthernetW5500
|
||||
};
|
||||
|
||||
class EthernetUDP;
|
||||
class EthernetClient;
|
||||
class EthernetServer;
|
||||
class DhcpClass;
|
||||
|
||||
class EthernetClass {
|
||||
private:
|
||||
static IPAddress _dnsServerAddress;
|
||||
static DhcpClass* _dhcp;
|
||||
public:
|
||||
// KH
|
||||
uint8_t _maxSockNum;
|
||||
uint8_t _pinCS;
|
||||
uint8_t _pinRST;
|
||||
|
||||
void setRstPin(uint8_t pinRST = 9); // for WIZ550io or USR-ES1, must set befor Ethernet.begin
|
||||
void setCsPin(uint8_t pinCS = 10); // must set befor Ethernet.begin
|
||||
|
||||
// Initialize with less sockets but more RX/TX Buffer
|
||||
// maxSockNum = 1 Socket 0 -> RX/TX Buffer 16k
|
||||
// maxSockNum = 2 Socket 0, 1 -> RX/TX Buffer 8k
|
||||
// maxSockNum = 4 Socket 0...3 -> RX/TX Buffer 4k
|
||||
// maxSockNum = 8 (Standard) all sockets -> RX/TX Buffer 2k
|
||||
// be carefull of the MAX_SOCK_NUM, because in the moment it can't dynamicly changed
|
||||
void initMaxSockNum(uint8_t maxSockNum = 8);
|
||||
|
||||
uint8_t softreset(); // can set only after Ethernet.begin
|
||||
void hardreset(); // You need to set the Rst pin
|
||||
|
||||
// Initialise the Ethernet shield to use the provided MAC address and
|
||||
// gain the rest of the configuration through DHCP.
|
||||
// Returns 0 if the DHCP configuration failed, and 1 if it succeeded
|
||||
int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);
|
||||
int maintain();
|
||||
EthernetLinkStatus linkStatus();
|
||||
EthernetHardwareStatus hardwareStatus();
|
||||
|
||||
// Manual configuration
|
||||
void begin(uint8_t *mac, IPAddress ip);
|
||||
void begin(uint8_t *mac, IPAddress ip, IPAddress dns);
|
||||
void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway);
|
||||
void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
|
||||
void init(uint8_t sspin = 10);
|
||||
|
||||
void MACAddress(uint8_t *mac_address);
|
||||
IPAddress localIP();
|
||||
IPAddress subnetMask();
|
||||
IPAddress gatewayIP();
|
||||
IPAddress dnsServerIP() { return _dnsServerAddress; }
|
||||
|
||||
void setMACAddress(const uint8_t *mac_address);
|
||||
void setLocalIP(const IPAddress local_ip);
|
||||
void setSubnetMask(const IPAddress subnet);
|
||||
void setGatewayIP(const IPAddress gateway);
|
||||
void setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; }
|
||||
void setRetransmissionTimeout(uint16_t milliseconds);
|
||||
void setRetransmissionCount(uint8_t num);
|
||||
|
||||
friend class EthernetClient;
|
||||
friend class EthernetServer;
|
||||
friend class EthernetUDP;
|
||||
private:
|
||||
// Opens a socket(TCP or UDP or IP_RAW mode)
|
||||
uint8_t socketBegin(uint8_t protocol, uint16_t port);
|
||||
uint8_t socketBeginMulticast(uint8_t protocol, IPAddress ip,uint16_t port);
|
||||
uint8_t socketStatus(uint8_t s);
|
||||
// Close socket
|
||||
void socketClose(uint8_t s);
|
||||
// Establish TCP connection (Active connection)
|
||||
void socketConnect(uint8_t s, uint8_t * addr, uint16_t port);
|
||||
// disconnect the connection
|
||||
void socketDisconnect(uint8_t s);
|
||||
// Establish TCP connection (Passive connection)
|
||||
uint8_t socketListen(uint8_t s);
|
||||
// Send data (TCP)
|
||||
uint16_t socketSend(uint8_t s, const uint8_t * buf, uint16_t len);
|
||||
uint16_t socketSendAvailable(uint8_t s);
|
||||
// Receive data (TCP)
|
||||
int socketRecv(uint8_t s, uint8_t * buf, int16_t len);
|
||||
uint16_t socketRecvAvailable(uint8_t s);
|
||||
uint8_t socketPeek(uint8_t s);
|
||||
// sets up a UDP datagram, the data for which will be provided by one
|
||||
// or more calls to bufferData and then finally sent with sendUDP.
|
||||
// return true if the datagram was successfully set up, or false if there was an error
|
||||
bool socketStartUDP(uint8_t s, uint8_t* addr, uint16_t port);
|
||||
// copy up to len bytes of data from buf into a UDP datagram to be
|
||||
// sent later by sendUDP. Allows datagrams to be built up from a series of bufferData calls.
|
||||
// return Number of bytes successfully buffered
|
||||
uint16_t socketBufferData(uint8_t s, uint16_t offset, const uint8_t* buf, uint16_t len);
|
||||
// Send a UDP datagram built up from a sequence of startUDP followed by one or more
|
||||
// calls to bufferData.
|
||||
// return true if the datagram was successfully sent, or false if there was an error
|
||||
bool socketSendUDP(uint8_t s);
|
||||
// Initialize the "random" source port number
|
||||
void socketPortRand(uint16_t n);
|
||||
};
|
||||
|
||||
extern EthernetClass Ethernet;
|
||||
|
||||
|
||||
#define UDP_TX_PACKET_MAX_SIZE 24
|
||||
|
||||
class EthernetUDP : public UDP {
|
||||
private:
|
||||
uint16_t _port; // local port to listen on
|
||||
IPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed
|
||||
uint16_t _remotePort; // remote port for the incoming packet whilst it's being processed
|
||||
uint16_t _offset; // offset into the packet being sent
|
||||
|
||||
protected:
|
||||
uint8_t sockindex;
|
||||
uint16_t _remaining; // remaining bytes of incoming packet yet to be processed
|
||||
|
||||
public:
|
||||
EthernetUDP() : sockindex(MAX_SOCK_NUM) {} // Constructor
|
||||
virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
|
||||
virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
|
||||
virtual void stop(); // Finish with the UDP socket
|
||||
|
||||
// Sending UDP packets
|
||||
|
||||
// Start building up a packet to send to the remote host specific in ip and port
|
||||
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
|
||||
virtual int beginPacket(IPAddress ip, uint16_t port);
|
||||
// Start building up a packet to send to the remote host specific in host and port
|
||||
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
|
||||
virtual int beginPacket(const char *host, uint16_t port);
|
||||
// Finish off this packet and send it
|
||||
// Returns 1 if the packet was sent successfully, 0 if there was an error
|
||||
virtual int endPacket();
|
||||
// Write a single byte into the packet
|
||||
virtual size_t write(uint8_t);
|
||||
// Write size bytes from buffer into the packet
|
||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||
|
||||
using Print::write;
|
||||
|
||||
// Start processing the next available incoming packet
|
||||
// Returns the size of the packet in bytes, or 0 if no packets are available
|
||||
virtual int parsePacket();
|
||||
// Number of bytes remaining in the current packet
|
||||
virtual int available();
|
||||
// Read a single byte from the current packet
|
||||
virtual int read();
|
||||
// Read up to len bytes from the current packet and place them into buffer
|
||||
// Returns the number of bytes read, or 0 if none are available
|
||||
virtual int read(unsigned char* buffer, size_t len);
|
||||
// Read up to len characters from the current packet and place them into buffer
|
||||
// Returns the number of characters read, or 0 if none are available
|
||||
virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
|
||||
// Return the next byte from the current packet without moving on to the next byte
|
||||
virtual int peek();
|
||||
virtual void flush(); // Finish reading the current packet
|
||||
|
||||
// Return the IP address of the host who sent the current incoming packet
|
||||
virtual IPAddress remoteIP() { return _remoteIP; };
|
||||
// Return the port of the host who sent the current incoming packet
|
||||
virtual uint16_t remotePort() { return _remotePort; };
|
||||
virtual uint16_t localPort() { return _port; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class EthernetClient : public Client {
|
||||
public:
|
||||
|
||||
EthernetClient() : sockindex(MAX_SOCK_NUM), _timeout(5000) { }
|
||||
EthernetClient(uint8_t s) : sockindex(s), _timeout(5000) { }
|
||||
|
||||
uint8_t status();
|
||||
virtual int connect(IPAddress ip, uint16_t port);
|
||||
virtual int connect(const char *host, uint16_t port);
|
||||
virtual int availableForWrite(void);
|
||||
virtual size_t write(uint8_t);
|
||||
virtual size_t write(const uint8_t *buf, size_t size);
|
||||
|
||||
virtual int available();
|
||||
virtual int read();
|
||||
virtual int read(uint8_t *buf, size_t size);
|
||||
virtual int peek();
|
||||
virtual void flush();
|
||||
virtual void stop();
|
||||
virtual uint8_t connected();
|
||||
virtual operator bool() { return sockindex < MAX_SOCK_NUM; }
|
||||
virtual bool operator==(const bool value) { return bool() == value; }
|
||||
virtual bool operator!=(const bool value) { return bool() != value; }
|
||||
virtual bool operator==(const EthernetClient&);
|
||||
virtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); }
|
||||
uint8_t getSocketNumber() const { return sockindex; }
|
||||
virtual uint16_t localPort();
|
||||
virtual IPAddress remoteIP();
|
||||
virtual uint16_t remotePort();
|
||||
virtual void setConnectionTimeout(uint16_t timeout) { _timeout = timeout; }
|
||||
|
||||
friend class EthernetServer;
|
||||
|
||||
using Print::write;
|
||||
|
||||
private:
|
||||
uint8_t sockindex; // MAX_SOCK_NUM means client not in use
|
||||
uint16_t _timeout;
|
||||
};
|
||||
|
||||
|
||||
class EthernetServer : public Server {
|
||||
private:
|
||||
uint16_t _port;
|
||||
public:
|
||||
EthernetServer(uint16_t port) : _port(port) { }
|
||||
EthernetClient available();
|
||||
EthernetClient accept();
|
||||
virtual void begin();
|
||||
virtual size_t write(uint8_t);
|
||||
virtual size_t write(const uint8_t *buf, size_t size);
|
||||
virtual operator bool();
|
||||
using Print::write;
|
||||
//void statusreport();
|
||||
|
||||
// TODO: make private when socket allocation moves to EthernetClass
|
||||
static uint16_t server_port[MAX_SOCK_NUM];
|
||||
};
|
||||
|
||||
|
||||
class DhcpClass {
|
||||
private:
|
||||
uint32_t _dhcpInitialTransactionId;
|
||||
uint32_t _dhcpTransactionId;
|
||||
uint8_t _dhcpMacAddr[6];
|
||||
#ifdef __arm__
|
||||
uint8_t _dhcpLocalIp[4] __attribute__((aligned(4)));
|
||||
uint8_t _dhcpSubnetMask[4] __attribute__((aligned(4)));
|
||||
uint8_t _dhcpGatewayIp[4] __attribute__((aligned(4)));
|
||||
uint8_t _dhcpDhcpServerIp[4] __attribute__((aligned(4)));
|
||||
uint8_t _dhcpDnsServerIp[4] __attribute__((aligned(4)));
|
||||
#else
|
||||
uint8_t _dhcpLocalIp[4];
|
||||
uint8_t _dhcpSubnetMask[4];
|
||||
uint8_t _dhcpGatewayIp[4];
|
||||
uint8_t _dhcpDhcpServerIp[4];
|
||||
uint8_t _dhcpDnsServerIp[4];
|
||||
#endif
|
||||
uint32_t _dhcpLeaseTime;
|
||||
uint32_t _dhcpT1, _dhcpT2;
|
||||
uint32_t _renewInSec;
|
||||
uint32_t _rebindInSec;
|
||||
unsigned long _timeout;
|
||||
unsigned long _responseTimeout;
|
||||
unsigned long _lastCheckLeaseMillis;
|
||||
uint8_t _dhcp_state;
|
||||
EthernetUDP _dhcpUdpSocket;
|
||||
|
||||
int request_DHCP_lease();
|
||||
void reset_DHCP_lease();
|
||||
void presend_DHCP();
|
||||
void send_DHCP_MESSAGE(uint8_t, uint16_t);
|
||||
void printByte(char *, uint8_t);
|
||||
|
||||
uint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId);
|
||||
public:
|
||||
IPAddress getLocalIp();
|
||||
IPAddress getSubnetMask();
|
||||
IPAddress getGatewayIp();
|
||||
IPAddress getDhcpServerIp();
|
||||
IPAddress getDnsServerIp();
|
||||
|
||||
int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);
|
||||
int checkLease();
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,244 @@
|
||||
/****************************************************************************************************************************
|
||||
EthernetServer.cpp
|
||||
|
||||
EthernetWebServer is a library for the Ethernet shields to run WebServer
|
||||
|
||||
Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer
|
||||
Licensed under MIT license
|
||||
Version: 1.0.9
|
||||
|
||||
Copyright 2018 Paul Stoffregen
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries
|
||||
1.0.1 K Hoang 20/02/2020 Add support to lambda functions
|
||||
1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60
|
||||
1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards
|
||||
1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards
|
||||
1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense,
|
||||
Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc.
|
||||
More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge
|
||||
1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards
|
||||
1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards
|
||||
1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards.
|
||||
1.0.9 K Hoang 15/05/2020 Add EthernetWrapper.h for easier W5x00 support as well as more Ethernet libs in the future.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "Ethernet.h"
|
||||
#include "utility/w5100.h"
|
||||
|
||||
uint16_t EthernetServer::server_port[MAX_SOCK_NUM];
|
||||
|
||||
|
||||
void EthernetServer::begin()
|
||||
{
|
||||
uint8_t sockindex = Ethernet.socketBegin(SnMR::TCP, _port);
|
||||
if (sockindex < MAX_SOCK_NUM)
|
||||
{
|
||||
if (Ethernet.socketListen(sockindex))
|
||||
{
|
||||
server_port[sockindex] = _port;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ethernet.socketDisconnect(sockindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EthernetClient EthernetServer::available()
|
||||
{
|
||||
bool listening = false;
|
||||
uint8_t sockindex = MAX_SOCK_NUM;
|
||||
uint8_t chip, maxindex=MAX_SOCK_NUM;
|
||||
|
||||
chip = W5100.getChip();
|
||||
|
||||
if (!chip)
|
||||
return EthernetClient(MAX_SOCK_NUM);
|
||||
|
||||
//KH, set W5100 to max 2 sockets to increase buffer size
|
||||
if (chip == 51)
|
||||
{
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
maxindex = 2; // W5100 chip never supports more than 4 sockets
|
||||
#else
|
||||
maxindex = 4; // W5100 chip never supports more than 4 sockets. Original
|
||||
#endif
|
||||
}
|
||||
|
||||
for (uint8_t i=0; i < maxindex; i++)
|
||||
{
|
||||
if (server_port[i] == _port)
|
||||
{
|
||||
uint8_t stat = Ethernet.socketStatus(i);
|
||||
if (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT)
|
||||
{
|
||||
if (Ethernet.socketRecvAvailable(i) > 0)
|
||||
{
|
||||
sockindex = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
// remote host closed connection, our end still open
|
||||
if (stat == SnSR::CLOSE_WAIT)
|
||||
{
|
||||
Ethernet.socketDisconnect(i);
|
||||
// status becomes LAST_ACK for short time
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (stat == SnSR::LISTEN)
|
||||
{
|
||||
listening = true;
|
||||
}
|
||||
else if (stat == SnSR::CLOSED)
|
||||
{
|
||||
server_port[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!listening)
|
||||
{
|
||||
begin();
|
||||
}
|
||||
|
||||
return EthernetClient(sockindex);
|
||||
}
|
||||
|
||||
EthernetClient EthernetServer::accept()
|
||||
{
|
||||
bool listening = false;
|
||||
uint8_t sockindex = MAX_SOCK_NUM;
|
||||
uint8_t chip, maxindex=MAX_SOCK_NUM;
|
||||
|
||||
chip = W5100.getChip();
|
||||
|
||||
if (!chip)
|
||||
return EthernetClient(MAX_SOCK_NUM);
|
||||
|
||||
//KH, set W5100 to max 2 sockets to increase buffer size
|
||||
if (chip == 51)
|
||||
{
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
maxindex = 2; // W5100 chip never supports more than 4 sockets
|
||||
#else
|
||||
maxindex = 4; // W5100 chip never supports more than 4 sockets. Original
|
||||
#endif
|
||||
}
|
||||
|
||||
for (uint8_t i=0; i < maxindex; i++)
|
||||
{
|
||||
if (server_port[i] == _port)
|
||||
{
|
||||
uint8_t stat = Ethernet.socketStatus(i);
|
||||
|
||||
if (sockindex == MAX_SOCK_NUM && (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT))
|
||||
{
|
||||
// Return the connected client even if no data received.
|
||||
// Some protocols like FTP expect the server to send the
|
||||
// first data.
|
||||
sockindex = i;
|
||||
server_port[i] = 0; // only return the client once
|
||||
}
|
||||
else if (stat == SnSR::LISTEN)
|
||||
{
|
||||
listening = true;
|
||||
}
|
||||
else if (stat == SnSR::CLOSED)
|
||||
{
|
||||
server_port[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!listening)
|
||||
begin();
|
||||
|
||||
return EthernetClient(sockindex);
|
||||
}
|
||||
|
||||
EthernetServer::operator bool()
|
||||
{
|
||||
uint8_t maxindex=MAX_SOCK_NUM;
|
||||
|
||||
//KH, set W5100 to max 2 sockets to increase buffer size
|
||||
if (W5100.getChip() == 51)
|
||||
{
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
maxindex = 2; // W5100 chip never supports more than 4 sockets
|
||||
#else
|
||||
maxindex = 4; // W5100 chip never supports more than 4 sockets. Original
|
||||
#endif
|
||||
}
|
||||
|
||||
for (uint8_t i=0; i < maxindex; i++)
|
||||
{
|
||||
if (server_port[i] == _port)
|
||||
{
|
||||
if (Ethernet.socketStatus(i) == SnSR::LISTEN)
|
||||
{
|
||||
return true; // server is listening for incoming clients
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t EthernetServer::write(uint8_t b)
|
||||
{
|
||||
return write(&b, 1);
|
||||
}
|
||||
|
||||
size_t EthernetServer::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
uint8_t chip, maxindex=MAX_SOCK_NUM;
|
||||
|
||||
chip = W5100.getChip();
|
||||
if (!chip) return 0;
|
||||
|
||||
//KH, set W5100 to max 2 sockets to increase buffer size
|
||||
if (chip == 51)
|
||||
{
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
maxindex = 2; // W5100 chip never supports more than 4 sockets
|
||||
#else
|
||||
maxindex = 4; // W5100 chip never supports more than 4 sockets. Original
|
||||
#endif
|
||||
}
|
||||
|
||||
available();
|
||||
|
||||
for (uint8_t i=0; i < maxindex; i++)
|
||||
{
|
||||
if (server_port[i] == _port)
|
||||
{
|
||||
if (Ethernet.socketStatus(i) == SnSR::ESTABLISHED)
|
||||
{
|
||||
Ethernet.socketSend(i, buffer, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
@ -0,0 +1,711 @@
|
||||
/****************************************************************************************************************************
|
||||
w5100.cpp - Driver for W5x00
|
||||
|
||||
EthernetWebServer is a library for the Ethernet shields to run WebServer
|
||||
|
||||
Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer
|
||||
Licensed under MIT license
|
||||
Version: 1.0.9
|
||||
|
||||
Copyright 2018 Paul Stoffregen
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries
|
||||
1.0.1 K Hoang 20/02/2020 Add support to lambda functions
|
||||
1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60
|
||||
1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards
|
||||
1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards
|
||||
1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense,
|
||||
Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc.
|
||||
More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge
|
||||
1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards
|
||||
1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards
|
||||
1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards.
|
||||
1.0.9 K Hoang 15/05/2020 Add EthernetWrapper.h for easier W5x00 support as well as more Ethernet libs in the future.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "Ethernet.h"
|
||||
#include "w5100.h"
|
||||
|
||||
#define W5100_DEBUG 1
|
||||
|
||||
/***************************************************/
|
||||
/** Default SS pin setting **/
|
||||
/***************************************************/
|
||||
|
||||
// If variant.h or other headers specifically define the
|
||||
// default SS pin for ethernet, use it.
|
||||
#if defined(PIN_SPI_SS_ETHERNET_LIB)
|
||||
|
||||
#define SS_PIN_DEFAULT PIN_SPI_SS_ETHERNET_LIB
|
||||
//KH
|
||||
#warning w5100.cpp Use PIN_SPI_SS_ETHERNET_LIB defined, change SS_PIN_DEFAULT to PIN_SPI_SS_ETHERNET_LIB
|
||||
|
||||
// MKR boards default to pin 5 for MKR ETH
|
||||
// Pins 8-10 are MOSI/SCK/MISO on MRK, so don't use pin 10
|
||||
#elif defined(USE_ARDUINO_MKR_PIN_LAYOUT) || defined(ARDUINO_SAMD_MKRZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWAN1300)
|
||||
|
||||
#define SS_PIN_DEFAULT 5
|
||||
//KH
|
||||
#warning w5100.cpp Use MKR, change SS_PIN_DEFAULT to 5
|
||||
|
||||
// For boards using AVR, assume shields with SS on pin 10
|
||||
// will be used. This allows for Arduino Mega (where
|
||||
// SS is pin 53) and Arduino Leonardo (where SS is pin 17)
|
||||
// to work by default with Arduino Ethernet Shield R2 & R3.
|
||||
#elif defined(__AVR__)
|
||||
|
||||
#define SS_PIN_DEFAULT 10
|
||||
//KH
|
||||
#warning w5100.cpp Use __AVR__, change SS_PIN_DEFAULT to 10
|
||||
|
||||
// If variant.h or other headers define these names
|
||||
// use them if none of the other cases match
|
||||
#elif defined(PIN_SPI_SS)
|
||||
|
||||
#if defined(__SAMD21G18A__)
|
||||
//10 - 2 (6 conflict) all not OK for Nano 33 IoT !!! SPI corrupted???
|
||||
#warning w5100.cpp Use __SAMD21G18A__, change SS_PIN_DEFAULT to 10
|
||||
#define SS_PIN_DEFAULT 10
|
||||
#else
|
||||
#define SS_PIN_DEFAULT PIN_SPI_SS
|
||||
|
||||
//KH
|
||||
#warning w5100.cpp Use PIN_SPI_SS defined, change SS_PIN_DEFAULT to PIN_SPI_SS
|
||||
#endif
|
||||
|
||||
#elif defined(CORE_SS0_PIN)
|
||||
#define SS_PIN_DEFAULT CORE_SS0_PIN
|
||||
|
||||
//KH
|
||||
#warning w5100.cpp Use CORE_SS0_PIN defined, change SS_PIN_DEFAULT to CORE_SS0_PIN
|
||||
|
||||
//KH for ESP32
|
||||
#elif defined(ESP32)
|
||||
//pin SS already defined in ESP32 as pin 5, don't use this as conflict with SPIFFS, EEPROM, etc.
|
||||
// Use in GPIO22
|
||||
#warning w5100.cpp Use ESP32, change SS_PIN_DEFAULT to GPIO22, MOSI(23), MISO(19), SCK(18)
|
||||
#define SS_PIN_DEFAULT 22 //SS
|
||||
///////
|
||||
|
||||
//KH for ESP8266
|
||||
#elif defined(ESP8266)
|
||||
//pin SS already defined in ESP8266 as pin 15. Conflict => Move to pin GPIO4 (D2)
|
||||
#warning w5100.cpp Use ESP8266, change SS_PIN_DEFAULT to SS(4), MOSI(13), MISO(12), SCK(14)
|
||||
#define SS_PIN_DEFAULT D2 // GPIO4, SS
|
||||
|
||||
///////
|
||||
|
||||
// As a final fallback, use pin 10
|
||||
#else
|
||||
#define SS_PIN_DEFAULT 10
|
||||
|
||||
//KH
|
||||
#warning w5100.cpp Use fallback, change SS_PIN_DEFAULT to 10
|
||||
|
||||
#endif
|
||||
|
||||
// W5100 controller instance
|
||||
uint8_t W5100Class::chip = 0;
|
||||
uint8_t W5100Class::CH_BASE_MSB;
|
||||
uint8_t W5100Class::ss_pin = SS_PIN_DEFAULT;
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
uint16_t W5100Class::SSIZE = 2048;
|
||||
uint16_t W5100Class::SMASK = 0x07FF;
|
||||
#endif
|
||||
W5100Class W5100;
|
||||
|
||||
// pointers and bitmasks for optimized SS pin
|
||||
#if defined(__AVR__)
|
||||
volatile uint8_t * W5100Class::ss_pin_reg;
|
||||
uint8_t W5100Class::ss_pin_mask;
|
||||
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)
|
||||
volatile uint8_t * W5100Class::ss_pin_reg;
|
||||
#elif defined(__IMXRT1062__)
|
||||
volatile uint32_t * W5100Class::ss_pin_reg;
|
||||
uint32_t W5100Class::ss_pin_mask;
|
||||
#elif defined(__MKL26Z64__)
|
||||
volatile uint8_t * W5100Class::ss_pin_reg;
|
||||
uint8_t W5100Class::ss_pin_mask;
|
||||
#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)
|
||||
volatile uint32_t * W5100Class::ss_pin_reg;
|
||||
uint32_t W5100Class::ss_pin_mask;
|
||||
#elif defined(__PIC32MX__)
|
||||
volatile uint32_t * W5100Class::ss_pin_reg;
|
||||
uint32_t W5100Class::ss_pin_mask;
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
volatile uint32_t * W5100Class::ss_pin_reg;
|
||||
uint32_t W5100Class::ss_pin_mask;
|
||||
#elif defined(__SAMD21G18A__)
|
||||
volatile uint32_t * W5100Class::ss_pin_reg;
|
||||
uint32_t W5100Class::ss_pin_mask;
|
||||
#warning w5100.cpp Use __SAMD21G18A__
|
||||
#endif
|
||||
|
||||
// KH
|
||||
uint8_t W5100Class::init(uint8_t socketNumbers, uint8_t new_ss_pin)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if (initialized) return 1;
|
||||
|
||||
// Many Ethernet shields have a CAT811 or similar reset chip
|
||||
// connected to W5100 or W5200 chips. The W5200 will not work at
|
||||
// all, and may even drive its MISO pin, until given an active low
|
||||
// reset pulse! The CAT811 has a 240 ms typical pulse length, and
|
||||
// a 400 ms worst case maximum pulse length. MAX811 has a worst
|
||||
// case maximum 560 ms pulse length. This delay is meant to wait
|
||||
// until the reset pulse is ended. If your hardware has a shorter
|
||||
// reset time, this can be edited or removed.
|
||||
delay(560);
|
||||
|
||||
//W5100Class::ss_pin = new_ss_pin;
|
||||
|
||||
#if ( W5100_DEBUG > 0 )
|
||||
//KH
|
||||
Serial.print("\nW5100 init, using SS_PIN_DEFAULT = ");
|
||||
Serial.print(SS_PIN_DEFAULT);
|
||||
Serial.print(", new ss_pin = ");
|
||||
Serial.print(new_ss_pin);
|
||||
Serial.print(", W5100Class::ss_pin = ");
|
||||
Serial.println(W5100Class::ss_pin);
|
||||
#endif
|
||||
|
||||
SPI.begin();
|
||||
|
||||
initSS();
|
||||
resetSS();
|
||||
|
||||
// From #define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0)
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
|
||||
// Attempt W5200 detection first, because W5200 does not properly
|
||||
// reset its SPI state when CS goes high (inactive). Communication
|
||||
// from detecting the other chips can leave the W5200 in a state
|
||||
// where it won't recover, unless given a reset pulse.
|
||||
if (isW5200())
|
||||
{
|
||||
CH_BASE_MSB = 0x40;
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
#if MAX_SOCK_NUM <= 1
|
||||
SSIZE = 16384;
|
||||
#elif MAX_SOCK_NUM <= 2
|
||||
SSIZE = 8192;
|
||||
#elif MAX_SOCK_NUM <= 4
|
||||
SSIZE = 4096;
|
||||
#else
|
||||
SSIZE = 2048;
|
||||
#endif
|
||||
SMASK = SSIZE - 1;
|
||||
#endif
|
||||
for (i=0; i<MAX_SOCK_NUM; i++)
|
||||
{
|
||||
writeSnRX_SIZE(i, SSIZE >> 10);
|
||||
writeSnTX_SIZE(i, SSIZE >> 10);
|
||||
}
|
||||
for (; i<8; i++)
|
||||
{
|
||||
writeSnRX_SIZE(i, 0);
|
||||
writeSnTX_SIZE(i, 0);
|
||||
}
|
||||
|
||||
#if ( W5100_DEBUG > 0 )
|
||||
Serial.print("W5100::init: W5200, SSIZE =");
|
||||
Serial.println(SSIZE);
|
||||
#endif
|
||||
|
||||
// Try W5500 next. Wiznet finally seems to have implemented
|
||||
// SPI well with this chip. It appears to be very resilient,
|
||||
// so try it after the fragile W5200
|
||||
} else if (isW5500())
|
||||
{
|
||||
CH_BASE_MSB = 0x10;
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
#if MAX_SOCK_NUM <= 1
|
||||
SSIZE = 16384;
|
||||
#elif MAX_SOCK_NUM <= 2
|
||||
SSIZE = 8192;
|
||||
#elif MAX_SOCK_NUM <= 4
|
||||
SSIZE = 4096;
|
||||
#else
|
||||
SSIZE = 2048;
|
||||
#endif
|
||||
SMASK = SSIZE - 1;
|
||||
for (i=0; i<MAX_SOCK_NUM; i++)
|
||||
{
|
||||
writeSnRX_SIZE(i, SSIZE >> 10);
|
||||
writeSnTX_SIZE(i, SSIZE >> 10);
|
||||
}
|
||||
for (; i<8; i++)
|
||||
{
|
||||
writeSnRX_SIZE(i, 0);
|
||||
writeSnTX_SIZE(i, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ( W5100_DEBUG > 0 )
|
||||
Serial.print("W5100::init: W5500, SSIZE =");
|
||||
Serial.println(SSIZE);
|
||||
#endif
|
||||
|
||||
// Try W5100 last. This simple chip uses fixed 4 byte frames
|
||||
// for every 8 bit access. Terribly inefficient, but so simple
|
||||
// it recovers from "hearing" unsuccessful W5100 or W5200
|
||||
// communication. W5100 is also the only chip without a VERSIONR
|
||||
// register for identification, so we check this last.
|
||||
} else if (isW5100())
|
||||
{
|
||||
CH_BASE_MSB = 0x04;
|
||||
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
|
||||
#if MAX_SOCK_NUM <= 1
|
||||
SSIZE = 8192;
|
||||
writeTMSR(0x03);
|
||||
writeRMSR(0x03);
|
||||
#else
|
||||
SSIZE = 4096;
|
||||
writeTMSR(0x0A);
|
||||
writeRMSR(0x0A);
|
||||
#endif
|
||||
|
||||
SMASK = SSIZE - 1;
|
||||
#else
|
||||
|
||||
writeTMSR(0x55);
|
||||
writeRMSR(0x55);
|
||||
#endif
|
||||
|
||||
#if ( W5100_DEBUG > 0 )
|
||||
Serial.print("W5100::init: W5100, SSIZE =");
|
||||
Serial.println(SSIZE);
|
||||
#endif
|
||||
|
||||
// No hardware seems to be present. Or it could be a W5200
|
||||
// that's heard other SPI communication if its chip select
|
||||
// pin wasn't high when a SD card or other SPI chip was used.
|
||||
}
|
||||
else
|
||||
{
|
||||
#if ( W5100_DEBUG > 0 )
|
||||
Serial.println("no chip :-(");
|
||||
#endif
|
||||
|
||||
chip = 0;
|
||||
SPI.endTransaction();
|
||||
return 0; // no known chip is responding :-(
|
||||
}
|
||||
|
||||
SPI.endTransaction();
|
||||
initialized = true;
|
||||
return 1; // successful init
|
||||
}
|
||||
|
||||
// Soft reset the Wiznet chip, by writing to its MR register reset bit
|
||||
uint8_t W5100Class::softReset(void)
|
||||
{
|
||||
uint16_t count=0;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("Wiznet soft reset");
|
||||
#endif
|
||||
|
||||
// write to reset bit
|
||||
writeMR(0x80);
|
||||
// then wait for soft reset to complete
|
||||
do
|
||||
{
|
||||
uint8_t mr = readMR();
|
||||
|
||||
#if ( W5100_DEBUG > 2 )
|
||||
Serial.print("mr=");
|
||||
Serial.println(mr, HEX);
|
||||
#endif
|
||||
|
||||
if (mr == 0)
|
||||
return 1;
|
||||
|
||||
delay(1);
|
||||
} while (++count < 20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t W5100Class::isW5100(void)
|
||||
{
|
||||
chip = 51;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("W5100.cpp: detect W5100 chip");
|
||||
#endif
|
||||
|
||||
if (!softReset())
|
||||
return 0;
|
||||
|
||||
writeMR(0x10);
|
||||
if (readMR() != 0x10)
|
||||
return 0;
|
||||
|
||||
writeMR(0x12);
|
||||
if (readMR() != 0x12)
|
||||
return 0;
|
||||
|
||||
writeMR(0x00);
|
||||
if (readMR() != 0x00)
|
||||
return 0;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("chip is W5100");
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t W5100Class::isW5200(void)
|
||||
{
|
||||
chip = 52;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("W5100.cpp: detect W5200 chip");
|
||||
#endif
|
||||
|
||||
if (!softReset())
|
||||
return 0;
|
||||
|
||||
writeMR(0x08);
|
||||
if (readMR() != 0x08)
|
||||
return 0;
|
||||
|
||||
writeMR(0x10);
|
||||
if (readMR() != 0x10)
|
||||
return 0;
|
||||
|
||||
writeMR(0x00);
|
||||
if (readMR() != 0x00)
|
||||
return 0;
|
||||
|
||||
int ver = readVERSIONR_W5200();
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.print("version=");
|
||||
Serial.println(ver);
|
||||
#endif
|
||||
|
||||
if (ver != 3)
|
||||
return 0;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("chip is W5200");
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t W5100Class::isW5500(void)
|
||||
{
|
||||
chip = 55;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("W5100.cpp: detect W5500 chip");
|
||||
#endif
|
||||
|
||||
if (!softReset())
|
||||
return 0;
|
||||
|
||||
writeMR(0x08);
|
||||
if (readMR() != 0x08)
|
||||
return 0;
|
||||
|
||||
writeMR(0x10);
|
||||
if (readMR() != 0x10)
|
||||
return 0;
|
||||
|
||||
writeMR(0x00);
|
||||
if (readMR() != 0x00)
|
||||
return 0;
|
||||
|
||||
int ver = readVERSIONR_W5500();
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.print("version=");
|
||||
Serial.println(ver);
|
||||
#endif
|
||||
|
||||
if (ver != 4)
|
||||
return 0;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("chip is W5500");
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
W5100Linkstatus W5100Class::getLinkStatus()
|
||||
{
|
||||
uint8_t phystatus;
|
||||
|
||||
// KH
|
||||
if (!initialized) return UNKNOWN;
|
||||
|
||||
switch (chip)
|
||||
{
|
||||
case 52:
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
phystatus = readPSTATUS_W5200();
|
||||
SPI.endTransaction();
|
||||
if (phystatus & 0x20)
|
||||
return LINK_ON;
|
||||
|
||||
return LINK_OFF;
|
||||
|
||||
case 55:
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
phystatus = readPHYCFGR_W5500();
|
||||
SPI.endTransaction();
|
||||
if (phystatus & 0x01)
|
||||
return LINK_ON;
|
||||
|
||||
return LINK_OFF;
|
||||
|
||||
default:
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t W5100Class::write(uint16_t addr, const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint8_t cmd[8];
|
||||
|
||||
if (chip == 51)
|
||||
{
|
||||
for (uint16_t i=0; i<len; i++)
|
||||
{
|
||||
setSS();
|
||||
SPI.transfer(0xF0);
|
||||
SPI.transfer(addr >> 8);
|
||||
SPI.transfer(addr & 0xFF);
|
||||
addr++;
|
||||
SPI.transfer(buf[i]);
|
||||
resetSS();
|
||||
}
|
||||
}
|
||||
else if (chip == 52)
|
||||
{
|
||||
setSS();
|
||||
cmd[0] = addr >> 8;
|
||||
cmd[1] = addr & 0xFF;
|
||||
cmd[2] = ((len >> 8) & 0x7F) | 0x80;
|
||||
cmd[3] = len & 0xFF;
|
||||
SPI.transfer(cmd, 4);
|
||||
|
||||
#ifdef SPI_HAS_TRANSFER_BUF
|
||||
SPI.transfer(buf, NULL, len);
|
||||
#else
|
||||
// TODO: copy 8 bytes at a time to cmd[] and block transfer
|
||||
for (uint16_t i=0; i < len; i++)
|
||||
{
|
||||
SPI.transfer(buf[i]);
|
||||
}
|
||||
#endif
|
||||
resetSS();
|
||||
}
|
||||
else
|
||||
{
|
||||
// chip == 55
|
||||
setSS();
|
||||
if (addr < 0x100)
|
||||
{
|
||||
// common registers 00nn
|
||||
cmd[0] = 0;
|
||||
cmd[1] = addr & 0xFF;
|
||||
cmd[2] = 0x04;
|
||||
}
|
||||
else if (addr < 0x8000)
|
||||
{
|
||||
// socket registers 10nn, 11nn, 12nn, 13nn, etc
|
||||
cmd[0] = 0;
|
||||
cmd[1] = addr & 0xFF;
|
||||
cmd[2] = ((addr >> 3) & 0xE0) | 0x0C;
|
||||
}
|
||||
else if (addr < 0xC000)
|
||||
{
|
||||
// transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc
|
||||
// 10## #nnn nnnn nnnn
|
||||
cmd[0] = addr >> 8;
|
||||
cmd[1] = addr & 0xFF;
|
||||
#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1
|
||||
cmd[2] = 0x14; // 16K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2
|
||||
cmd[2] = ((addr >> 8) & 0x20) | 0x14; // 8K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4
|
||||
cmd[2] = ((addr >> 7) & 0x60) | 0x14; // 4K buffers
|
||||
#else
|
||||
cmd[2] = ((addr >> 6) & 0xE0) | 0x14; // 2K buffers
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// receive buffers
|
||||
cmd[0] = addr >> 8;
|
||||
cmd[1] = addr & 0xFF;
|
||||
#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1
|
||||
cmd[2] = 0x1C; // 16K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2
|
||||
cmd[2] = ((addr >> 8) & 0x20) | 0x1C; // 8K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4
|
||||
cmd[2] = ((addr >> 7) & 0x60) | 0x1C; // 4K buffers
|
||||
#else
|
||||
cmd[2] = ((addr >> 6) & 0xE0) | 0x1C; // 2K buffers
|
||||
#endif
|
||||
}
|
||||
|
||||
if (len <= 5)
|
||||
{
|
||||
for (uint8_t i=0; i < len; i++)
|
||||
{
|
||||
cmd[i + 3] = buf[i];
|
||||
}
|
||||
|
||||
SPI.transfer(cmd, len + 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
SPI.transfer(cmd, 3);
|
||||
#ifdef SPI_HAS_TRANSFER_BUF
|
||||
SPI.transfer(buf, NULL, len);
|
||||
#else
|
||||
// TODO: copy 8 bytes at a time to cmd[] and block transfer
|
||||
for (uint16_t i=0; i < len; i++)
|
||||
{
|
||||
SPI.transfer(buf[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
resetSS();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
uint16_t W5100Class::read(uint16_t addr, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint8_t cmd[4];
|
||||
|
||||
if (chip == 51)
|
||||
{
|
||||
for (uint16_t i=0; i < len; i++)
|
||||
{
|
||||
setSS();
|
||||
#if 1
|
||||
SPI.transfer(0x0F);
|
||||
SPI.transfer(addr >> 8);
|
||||
SPI.transfer(addr & 0xFF);
|
||||
addr++;
|
||||
buf[i] = SPI.transfer(0);
|
||||
#else
|
||||
cmd[0] = 0x0F;
|
||||
cmd[1] = addr >> 8;
|
||||
cmd[2] = addr & 0xFF;
|
||||
cmd[3] = 0;
|
||||
SPI.transfer(cmd, 4); // TODO: why doesn't this work?
|
||||
buf[i] = cmd[3];
|
||||
addr++;
|
||||
#endif
|
||||
resetSS();
|
||||
}
|
||||
}
|
||||
else if (chip == 52)
|
||||
{
|
||||
setSS();
|
||||
cmd[0] = addr >> 8;
|
||||
cmd[1] = addr & 0xFF;
|
||||
cmd[2] = (len >> 8) & 0x7F;
|
||||
cmd[3] = len & 0xFF;
|
||||
SPI.transfer(cmd, 4);
|
||||
memset(buf, 0, len);
|
||||
SPI.transfer(buf, len);
|
||||
resetSS();
|
||||
}
|
||||
else
|
||||
{
|
||||
// chip == 55
|
||||
setSS();
|
||||
|
||||
if (addr < 0x100)
|
||||
{
|
||||
// common registers 00nn
|
||||
cmd[0] = 0;
|
||||
cmd[1] = addr & 0xFF;
|
||||
cmd[2] = 0x00;
|
||||
}
|
||||
else if (addr < 0x8000)
|
||||
{
|
||||
// socket registers 10nn, 11nn, 12nn, 13nn, etc
|
||||
cmd[0] = 0;
|
||||
cmd[1] = addr & 0xFF;
|
||||
cmd[2] = ((addr >> 3) & 0xE0) | 0x08;
|
||||
}
|
||||
else if (addr < 0xC000)
|
||||
{
|
||||
// transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc
|
||||
// 10## #nnn nnnn nnnn
|
||||
cmd[0] = addr >> 8;
|
||||
cmd[1] = addr & 0xFF;
|
||||
#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1
|
||||
cmd[2] = 0x10; // 16K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2
|
||||
cmd[2] = ((addr >> 8) & 0x20) | 0x10; // 8K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4
|
||||
cmd[2] = ((addr >> 7) & 0x60) | 0x10; // 4K buffers
|
||||
#else
|
||||
cmd[2] = ((addr >> 6) & 0xE0) | 0x10; // 2K buffers
|
||||
#endif
|
||||
} else
|
||||
{
|
||||
// receive buffers
|
||||
cmd[0] = addr >> 8;
|
||||
cmd[1] = addr & 0xFF;
|
||||
#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1
|
||||
cmd[2] = 0x18; // 16K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2
|
||||
cmd[2] = ((addr >> 8) & 0x20) | 0x18; // 8K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4
|
||||
cmd[2] = ((addr >> 7) & 0x60) | 0x18; // 4K buffers
|
||||
#else
|
||||
cmd[2] = ((addr >> 6) & 0xE0) | 0x18; // 2K buffers
|
||||
#endif
|
||||
}
|
||||
SPI.transfer(cmd, 3);
|
||||
memset(buf, 0, len);
|
||||
SPI.transfer(buf, len);
|
||||
resetSS();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd)
|
||||
{
|
||||
// Send command to socket
|
||||
writeSnCR(s, _cmd);
|
||||
// Wait for command to complete
|
||||
while (readSnCR(s)) ;
|
||||
}
|
@ -0,0 +1,642 @@
|
||||
/****************************************************************************************************************************
|
||||
w5100.h - Driver for W5x00
|
||||
|
||||
EthernetWebServer is a library for the Ethernet shields to run WebServer
|
||||
|
||||
Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer
|
||||
Licensed under MIT license
|
||||
Version: 1.0.9
|
||||
|
||||
Copyright 2018 Paul Stoffregen
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries
|
||||
1.0.1 K Hoang 20/02/2020 Add support to lambda functions
|
||||
1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60
|
||||
1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards
|
||||
1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards
|
||||
1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense,
|
||||
Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc.
|
||||
More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge
|
||||
1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards
|
||||
1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards
|
||||
1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards.
|
||||
1.0.9 K Hoang 15/05/2020 Add EthernetWrapper.h for easier W5x00 support as well as more Ethernet libs in the future.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
// w5100.h contains private W5x00 hardware "driver" level definitions
|
||||
// which are not meant to be exposed to other libraries or Arduino users
|
||||
|
||||
#ifndef W5100_H_INCLUDED
|
||||
#define W5100_H_INCLUDED
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#ifndef USE_W5100
|
||||
#define USE_W5100 false
|
||||
#else
|
||||
#define USE_W5100 true
|
||||
#endif
|
||||
|
||||
#if !USE_W5100
|
||||
|
||||
// Safe for W5200 and W5500, but also tested OK on W5100
|
||||
// Use 14MHz if you know your W5100 can't run
|
||||
// Higher SPI clock results in faster transfer to hosts on a LAN
|
||||
// or with very low packet latency. With ordinary internet latency,
|
||||
// the TCP window size & packet loss determine your overall speed.
|
||||
#warning Use 25MHz clock for W5200/W5500. Not for W5100
|
||||
#define SPI_ETHERNET_SETTINGS SPISettings(25000000, MSBFIRST, SPI_MODE0)
|
||||
|
||||
#else
|
||||
|
||||
// Safe for all chips but too slow
|
||||
#define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0)
|
||||
#warning Use 14MHz clock for W5100/W5200/W5500. Slow.
|
||||
|
||||
#endif
|
||||
|
||||
// Require Ethernet.h, because we need MAX_SOCK_NUM
|
||||
#ifndef ethernet_h_
|
||||
#error "Ethernet.h must be included before w5100.h"
|
||||
#endif
|
||||
|
||||
// Arduino 101's SPI can not run faster than 8 MHz.
|
||||
#if defined(ARDUINO_ARCH_ARC32)
|
||||
#undef SPI_ETHERNET_SETTINGS
|
||||
#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE0)
|
||||
#endif
|
||||
|
||||
// Arduino Zero can't use W5100-based shields faster than 8 MHz
|
||||
// https://github.com/arduino-libraries/Ethernet/issues/37#issuecomment-408036848
|
||||
// W5500 does seem to work at 12 MHz. Delete this if only using W5500
|
||||
#if defined(__SAMD21G18A__)
|
||||
#undef SPI_ETHERNET_SETTINGS
|
||||
//#warning Use SAMD21 architecture SPISettings(8000000, MSBFIRST, SPI_MODE3) => IP OK
|
||||
#warning Use SAMD21 architecture SPISettings(30000000, MSBFIRST, SPI_MODE3) => IP OK
|
||||
// Still not working !!! Original SPI_MODE0 not OK at all
|
||||
//#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE3)
|
||||
#define SPI_ETHERNET_SETTINGS SPISettings(30000000, MSBFIRST, SPI_MODE3)
|
||||
#endif
|
||||
|
||||
typedef uint8_t SOCKET;
|
||||
|
||||
class SnMR {
|
||||
public:
|
||||
static const uint8_t CLOSE = 0x00;
|
||||
static const uint8_t TCP = 0x21;
|
||||
static const uint8_t UDP = 0x02;
|
||||
static const uint8_t IPRAW = 0x03;
|
||||
static const uint8_t MACRAW = 0x04;
|
||||
static const uint8_t PPPOE = 0x05;
|
||||
static const uint8_t ND = 0x20;
|
||||
static const uint8_t MULTI = 0x80;
|
||||
};
|
||||
|
||||
enum SockCMD {
|
||||
Sock_OPEN = 0x01,
|
||||
Sock_LISTEN = 0x02,
|
||||
Sock_CONNECT = 0x04,
|
||||
Sock_DISCON = 0x08,
|
||||
Sock_CLOSE = 0x10,
|
||||
Sock_SEND = 0x20,
|
||||
Sock_SEND_MAC = 0x21,
|
||||
Sock_SEND_KEEP = 0x22,
|
||||
Sock_RECV = 0x40
|
||||
};
|
||||
|
||||
class SnIR {
|
||||
public:
|
||||
static const uint8_t SEND_OK = 0x10;
|
||||
static const uint8_t TIMEOUT = 0x08;
|
||||
static const uint8_t RECV = 0x04;
|
||||
static const uint8_t DISCON = 0x02;
|
||||
static const uint8_t CON = 0x01;
|
||||
};
|
||||
|
||||
class SnSR {
|
||||
public:
|
||||
static const uint8_t CLOSED = 0x00;
|
||||
static const uint8_t INIT = 0x13;
|
||||
static const uint8_t LISTEN = 0x14;
|
||||
static const uint8_t SYNSENT = 0x15;
|
||||
static const uint8_t SYNRECV = 0x16;
|
||||
static const uint8_t ESTABLISHED = 0x17;
|
||||
static const uint8_t FIN_WAIT = 0x18;
|
||||
static const uint8_t CLOSING = 0x1A;
|
||||
static const uint8_t TIME_WAIT = 0x1B;
|
||||
static const uint8_t CLOSE_WAIT = 0x1C;
|
||||
static const uint8_t LAST_ACK = 0x1D;
|
||||
static const uint8_t UDP = 0x22;
|
||||
static const uint8_t IPRAW = 0x32;
|
||||
static const uint8_t MACRAW = 0x42;
|
||||
static const uint8_t PPPOE = 0x5F;
|
||||
};
|
||||
|
||||
class IPPROTO {
|
||||
public:
|
||||
static const uint8_t IP = 0;
|
||||
static const uint8_t ICMP = 1;
|
||||
static const uint8_t IGMP = 2;
|
||||
static const uint8_t GGP = 3;
|
||||
static const uint8_t TCP = 6;
|
||||
static const uint8_t PUP = 12;
|
||||
static const uint8_t UDP = 17;
|
||||
static const uint8_t IDP = 22;
|
||||
static const uint8_t ND = 77;
|
||||
static const uint8_t RAW = 255;
|
||||
};
|
||||
|
||||
enum W5100Linkstatus {
|
||||
UNKNOWN,
|
||||
LINK_ON,
|
||||
LINK_OFF
|
||||
};
|
||||
|
||||
class W5100Class {
|
||||
|
||||
public:
|
||||
// KH
|
||||
uint8_t init(uint8_t socketNumbers = MAX_SOCK_NUM, uint8_t new_ss_pin = 10);
|
||||
|
||||
inline void setGatewayIp(const uint8_t * addr) { writeGAR(addr); }
|
||||
inline void getGatewayIp(uint8_t * addr) { readGAR(addr); }
|
||||
|
||||
inline void setSubnetMask(const uint8_t * addr) { writeSUBR(addr); }
|
||||
inline void getSubnetMask(uint8_t * addr) { readSUBR(addr); }
|
||||
|
||||
inline void setMACAddress(const uint8_t * addr) { writeSHAR(addr); }
|
||||
inline void getMACAddress(uint8_t * addr) { readSHAR(addr); }
|
||||
|
||||
inline void setIPAddress(const uint8_t * addr) { writeSIPR(addr); }
|
||||
inline void getIPAddress(uint8_t * addr) { readSIPR(addr); }
|
||||
|
||||
inline void setRetransmissionTime(uint16_t timeout) { writeRTR(timeout); }
|
||||
inline void setRetransmissionCount(uint8_t retry) { writeRCR(retry); }
|
||||
|
||||
static void execCmdSn(SOCKET s, SockCMD _cmd);
|
||||
|
||||
|
||||
// W5100 Registers
|
||||
// ---------------
|
||||
//private:
|
||||
public:
|
||||
static uint16_t write(uint16_t addr, const uint8_t *buf, uint16_t len);
|
||||
|
||||
static uint8_t write(uint16_t addr, uint8_t data)
|
||||
{
|
||||
return write(addr, &data, 1);
|
||||
}
|
||||
|
||||
static uint16_t read(uint16_t addr, uint8_t *buf, uint16_t len);
|
||||
|
||||
static uint8_t read(uint16_t addr)
|
||||
{
|
||||
uint8_t data;
|
||||
read(addr, &data, 1);
|
||||
return data;
|
||||
}
|
||||
|
||||
#define __GP_REGISTER8(name, address) \
|
||||
static inline void write##name(uint8_t _data) { \
|
||||
write(address, _data); \
|
||||
} \
|
||||
static inline uint8_t read##name() { \
|
||||
return read(address); \
|
||||
}
|
||||
#define __GP_REGISTER16(name, address) \
|
||||
static void write##name(uint16_t _data) { \
|
||||
uint8_t buf[2]; \
|
||||
buf[0] = _data >> 8; \
|
||||
buf[1] = _data & 0xFF; \
|
||||
write(address, buf, 2); \
|
||||
} \
|
||||
static uint16_t read##name() { \
|
||||
uint8_t buf[2]; \
|
||||
read(address, buf, 2); \
|
||||
return (buf[0] << 8) | buf[1]; \
|
||||
}
|
||||
#define __GP_REGISTER_N(name, address, size) \
|
||||
static uint16_t write##name(const uint8_t *_buff) { \
|
||||
return write(address, _buff, size); \
|
||||
} \
|
||||
static uint16_t read##name(uint8_t *_buff) { \
|
||||
return read(address, _buff, size); \
|
||||
}
|
||||
|
||||
W5100Linkstatus getLinkStatus();
|
||||
|
||||
public:
|
||||
__GP_REGISTER8 (MR, 0x0000); // Mode
|
||||
__GP_REGISTER_N(GAR, 0x0001, 4); // Gateway IP address
|
||||
__GP_REGISTER_N(SUBR, 0x0005, 4); // Subnet mask address
|
||||
__GP_REGISTER_N(SHAR, 0x0009, 6); // Source MAC address
|
||||
__GP_REGISTER_N(SIPR, 0x000F, 4); // Source IP address
|
||||
__GP_REGISTER8 (IR, 0x0015); // Interrupt
|
||||
__GP_REGISTER8 (IMR, 0x0016); // Interrupt Mask
|
||||
__GP_REGISTER16(RTR, 0x0017); // Timeout address
|
||||
__GP_REGISTER8 (RCR, 0x0019); // Retry count
|
||||
__GP_REGISTER8 (RMSR, 0x001A); // Receive memory size (W5100 only)
|
||||
__GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size (W5100 only)
|
||||
__GP_REGISTER8 (PATR, 0x001C); // Authentication type address in PPPoE mode
|
||||
__GP_REGISTER8 (PTIMER, 0x0028); // PPP LCP Request Timer
|
||||
__GP_REGISTER8 (PMAGIC, 0x0029); // PPP LCP Magic Number
|
||||
__GP_REGISTER_N(UIPR, 0x002A, 4); // Unreachable IP address in UDP mode (W5100 only)
|
||||
__GP_REGISTER16(UPORT, 0x002E); // Unreachable Port address in UDP mode (W5100 only)
|
||||
__GP_REGISTER8 (VERSIONR_W5200,0x001F); // Chip Version Register (W5200 only)
|
||||
__GP_REGISTER8 (VERSIONR_W5500,0x0039); // Chip Version Register (W5500 only)
|
||||
__GP_REGISTER8 (PSTATUS_W5200, 0x0035); // PHY Status
|
||||
__GP_REGISTER8 (PHYCFGR_W5500, 0x002E); // PHY Configuration register, default: 10111xxx
|
||||
|
||||
|
||||
#undef __GP_REGISTER8
|
||||
#undef __GP_REGISTER16
|
||||
#undef __GP_REGISTER_N
|
||||
|
||||
// W5100 Socket registers
|
||||
// ----------------------
|
||||
private:
|
||||
static uint16_t CH_BASE(void) {
|
||||
//if (chip == 55) return 0x1000;
|
||||
//if (chip == 52) return 0x4000;
|
||||
//return 0x0400;
|
||||
return CH_BASE_MSB << 8;
|
||||
}
|
||||
static uint8_t CH_BASE_MSB; // 1 redundant byte, saves ~80 bytes code on AVR
|
||||
static const uint16_t CH_SIZE = 0x0100;
|
||||
|
||||
static inline uint8_t readSn(SOCKET s, uint16_t addr)
|
||||
{
|
||||
return read(CH_BASE() + s * CH_SIZE + addr);
|
||||
}
|
||||
static inline uint8_t writeSn(SOCKET s, uint16_t addr, uint8_t data)
|
||||
{
|
||||
return write(CH_BASE() + s * CH_SIZE + addr, data);
|
||||
}
|
||||
static inline uint16_t readSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
return read(CH_BASE() + s * CH_SIZE + addr, buf, len);
|
||||
}
|
||||
static inline uint16_t writeSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
return write(CH_BASE() + s * CH_SIZE + addr, buf, len);
|
||||
}
|
||||
|
||||
#define __SOCKET_REGISTER8(name, address) \
|
||||
static inline void write##name(SOCKET _s, uint8_t _data) { \
|
||||
writeSn(_s, address, _data); \
|
||||
} \
|
||||
static inline uint8_t read##name(SOCKET _s) { \
|
||||
return readSn(_s, address); \
|
||||
}
|
||||
#define __SOCKET_REGISTER16(name, address) \
|
||||
static void write##name(SOCKET _s, uint16_t _data) { \
|
||||
uint8_t buf[2]; \
|
||||
buf[0] = _data >> 8; \
|
||||
buf[1] = _data & 0xFF; \
|
||||
writeSn(_s, address, buf, 2); \
|
||||
} \
|
||||
static uint16_t read##name(SOCKET _s) { \
|
||||
uint8_t buf[2]; \
|
||||
readSn(_s, address, buf, 2); \
|
||||
return (buf[0] << 8) | buf[1]; \
|
||||
}
|
||||
#define __SOCKET_REGISTER_N(name, address, size) \
|
||||
static uint16_t write##name(SOCKET _s, uint8_t *_buff) { \
|
||||
return writeSn(_s, address, _buff, size); \
|
||||
} \
|
||||
static uint16_t read##name(SOCKET _s, uint8_t *_buff) { \
|
||||
return readSn(_s, address, _buff, size); \
|
||||
}
|
||||
|
||||
public:
|
||||
__SOCKET_REGISTER8(SnMR, 0x0000) // Mode
|
||||
__SOCKET_REGISTER8(SnCR, 0x0001) // Command
|
||||
__SOCKET_REGISTER8(SnIR, 0x0002) // Interrupt
|
||||
__SOCKET_REGISTER8(SnSR, 0x0003) // Status
|
||||
__SOCKET_REGISTER16(SnPORT, 0x0004) // Source Port
|
||||
__SOCKET_REGISTER_N(SnDHAR, 0x0006, 6) // Destination Hardw Addr
|
||||
__SOCKET_REGISTER_N(SnDIPR, 0x000C, 4) // Destination IP Addr
|
||||
__SOCKET_REGISTER16(SnDPORT, 0x0010) // Destination Port
|
||||
__SOCKET_REGISTER16(SnMSSR, 0x0012) // Max Segment Size
|
||||
__SOCKET_REGISTER8(SnPROTO, 0x0014) // Protocol in IP RAW Mode
|
||||
__SOCKET_REGISTER8(SnTOS, 0x0015) // IP TOS
|
||||
__SOCKET_REGISTER8(SnTTL, 0x0016) // IP TTL
|
||||
__SOCKET_REGISTER8(SnRX_SIZE, 0x001E) // RX Memory Size (W5200 only)
|
||||
__SOCKET_REGISTER8(SnTX_SIZE, 0x001F) // RX Memory Size (W5200 only)
|
||||
__SOCKET_REGISTER16(SnTX_FSR, 0x0020) // TX Free Size
|
||||
__SOCKET_REGISTER16(SnTX_RD, 0x0022) // TX Read Pointer
|
||||
__SOCKET_REGISTER16(SnTX_WR, 0x0024) // TX Write Pointer
|
||||
__SOCKET_REGISTER16(SnRX_RSR, 0x0026) // RX Free Size
|
||||
__SOCKET_REGISTER16(SnRX_RD, 0x0028) // RX Read Pointer
|
||||
__SOCKET_REGISTER16(SnRX_WR, 0x002A) // RX Write Pointer (supported?)
|
||||
|
||||
#undef __SOCKET_REGISTER8
|
||||
#undef __SOCKET_REGISTER16
|
||||
#undef __SOCKET_REGISTER_N
|
||||
|
||||
|
||||
private:
|
||||
// KH
|
||||
bool initialized = false;
|
||||
static uint8_t chip;
|
||||
static uint8_t ss_pin;
|
||||
|
||||
static uint8_t isW5100(void);
|
||||
static uint8_t isW5200(void);
|
||||
static uint8_t isW5500(void);
|
||||
|
||||
public:
|
||||
// KH
|
||||
static uint8_t softReset(void);
|
||||
static uint8_t getChip(void) { return chip; }
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
static uint16_t SSIZE;
|
||||
static uint16_t SMASK;
|
||||
#else
|
||||
static const uint16_t SSIZE = 2048;
|
||||
static const uint16_t SMASK = 0x07FF;
|
||||
#endif
|
||||
static uint16_t SBASE(uint8_t socknum)
|
||||
{
|
||||
if (chip == 51)
|
||||
{
|
||||
return socknum * SSIZE + 0x4000;
|
||||
}
|
||||
else
|
||||
{
|
||||
return socknum * SSIZE + 0x8000;
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t RBASE(uint8_t socknum)
|
||||
{
|
||||
if (chip == 51) {
|
||||
return socknum * SSIZE + 0x6000;
|
||||
}
|
||||
else
|
||||
{
|
||||
return socknum * SSIZE + 0xC000;
|
||||
}
|
||||
}
|
||||
|
||||
static bool hasOffsetAddressMapping(void)
|
||||
{
|
||||
if (chip == 55)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void setSS(uint8_t pin) { ss_pin = pin; }
|
||||
|
||||
private:
|
||||
#if defined(__AVR__)
|
||||
|
||||
#warning Use AVR architecture
|
||||
|
||||
static volatile uint8_t *ss_pin_reg;
|
||||
static uint8_t ss_pin_mask;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin));
|
||||
ss_pin_mask = digitalPinToBitMask(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg) &= ~ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg) |= ss_pin_mask;
|
||||
}
|
||||
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)
|
||||
|
||||
#warning Use MK architecture
|
||||
|
||||
static volatile uint8_t *ss_pin_reg;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = portOutputRegister(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg+256) = 1;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg+128) = 1;
|
||||
}
|
||||
#elif defined(__IMXRT1062__)
|
||||
|
||||
#warning Use Teensy architecture
|
||||
|
||||
static volatile uint32_t *ss_pin_reg;
|
||||
static uint32_t ss_pin_mask;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin));
|
||||
ss_pin_mask = digitalPinToBitMask(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg+34) = ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg+33) = ss_pin_mask;
|
||||
|
||||
// Check https://forum.pjrc.com/threads/66758-Teensy-4-0-and-Ethernet-(WIZ5100-and-WIZ812)
|
||||
if (chip == 51)
|
||||
delayNanoseconds(10); // <-- fixes W5100 on Teensy 4
|
||||
}
|
||||
#elif defined(__MKL26Z64__)
|
||||
static volatile uint8_t *ss_pin_reg;
|
||||
static uint8_t ss_pin_mask;
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin));
|
||||
ss_pin_mask = digitalPinToBitMask(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg+8) = ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg+4) = ss_pin_mask;
|
||||
}
|
||||
#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)
|
||||
|
||||
#warning Use SAM3 architecture
|
||||
|
||||
static volatile uint32_t *ss_pin_reg;
|
||||
static uint32_t ss_pin_mask;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = &(digitalPinToPort(ss_pin)->PIO_PER);
|
||||
ss_pin_mask = digitalPinToBitMask(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg+13) = ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg+12) = ss_pin_mask;
|
||||
}
|
||||
#elif defined(__PIC32MX__)
|
||||
static volatile uint32_t *ss_pin_reg;
|
||||
static uint32_t ss_pin_mask;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = portModeRegister(digitalPinToPort(ss_pin));
|
||||
ss_pin_mask = digitalPinToBitMask(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg+8+1) = ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg+8+2) = ss_pin_mask;
|
||||
}
|
||||
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
|
||||
#warning Use ARDUINO_ARCH_ESP8266 architecture
|
||||
|
||||
static volatile uint32_t *ss_pin_reg;
|
||||
static uint32_t ss_pin_mask;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = (volatile uint32_t*)GPO;
|
||||
ss_pin_mask = 1 << ss_pin;
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
GPOC = ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
GPOS = ss_pin_mask;
|
||||
}
|
||||
|
||||
#elif defined(__SAMD21G18A__)
|
||||
|
||||
#warning Use SAMD21 architecture
|
||||
|
||||
static volatile uint32_t *ss_pin_reg;
|
||||
static uint32_t ss_pin_mask;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = portModeRegister(digitalPinToPort(ss_pin));
|
||||
ss_pin_mask = digitalPinToBitMask(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg+5) = ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg+6) = ss_pin_mask;
|
||||
}
|
||||
#else
|
||||
|
||||
#warning Use Default architecture
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
digitalWrite(ss_pin, LOW);
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
digitalWrite(ss_pin, HIGH);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
extern W5100Class W5100;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#ifndef htons
|
||||
#define htons(x) ( (((x)<<8)&0xFF00) | (((x)>>8)&0xFF) )
|
||||
#endif
|
||||
|
||||
#ifndef ntohs
|
||||
#define ntohs(x) htons(x)
|
||||
#endif
|
||||
|
||||
#ifndef htonl
|
||||
#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
|
||||
((x)<< 8 & 0x00FF0000UL) | \
|
||||
((x)>> 8 & 0x0000FF00UL) | \
|
||||
((x)>>24 & 0x000000FFUL) )
|
||||
#endif
|
||||
|
||||
#ifndef ntohl
|
||||
#define ntohl(x) htonl(x)
|
||||
#endif
|
||||
|
||||
#endif //W5100_H_INCLUDED
|
@ -0,0 +1,262 @@
|
||||
/*
|
||||
modified 12 Aug 2013
|
||||
by Soohwan Kim (suhwan@wiznet.co.kr)
|
||||
|
||||
- 10 Apr. 2015
|
||||
Added support for Arduino Ethernet Shield 2
|
||||
by Arduino.org team
|
||||
|
||||
*/
|
||||
|
||||
#include "Ethernet2.h"
|
||||
#include "Dhcp.h"
|
||||
|
||||
// XXX: don't make assumptions about the value of MAX_SOCK_NUM.
|
||||
uint8_t EthernetClass::_state[MAX_SOCK_NUM] = { 0, };
|
||||
uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = { 0, };
|
||||
|
||||
|
||||
|
||||
#if defined(WIZ550io_WITH_MACADDRESS)
|
||||
int EthernetClass::begin(void)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var _mac_address
|
||||
//byte mac_address[6] ={0,};
|
||||
//////
|
||||
|
||||
if (_dhcp != NULL) {
|
||||
delete _dhcp;
|
||||
}
|
||||
_dhcp = new DhcpClass();
|
||||
|
||||
// Initialise the basic info
|
||||
w5500.init(w5500_cspin);
|
||||
w5500.setIPAddress(IPAddress(0,0,0,0).raw_address());
|
||||
|
||||
// KH mod
|
||||
w5500.getMACAddress(_mac_address);
|
||||
|
||||
// Now try to get our config info from a DHCP server
|
||||
int ret = _dhcp->beginWithDHCP(_mac_address);
|
||||
//////
|
||||
|
||||
if(ret == 1)
|
||||
{
|
||||
// We've successfully found a DHCP server and got our configuration info, so set things
|
||||
// accordingly
|
||||
w5500.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
w5500.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
w5500.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
_dnsDomainName = _dhcp->getDnsDomainName();
|
||||
_hostName = _dhcp->getHostName();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EthernetClass::begin(IPAddress local_ip)
|
||||
{
|
||||
// Assume the DNS server will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress dns_server = local_ip;
|
||||
dns_server[3] = 1;
|
||||
begin(local_ip, dns_server);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(IPAddress local_ip, IPAddress dns_server)
|
||||
{
|
||||
// Assume the gateway will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress gateway = local_ip;
|
||||
gateway[3] = 1;
|
||||
begin(local_ip, dns_server, gateway);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(IPAddress local_ip, IPAddress dns_server, IPAddress gateway)
|
||||
{
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
begin(local_ip, dns_server, gateway, subnet);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet)
|
||||
{
|
||||
w5500.init(w5500_cspin);
|
||||
w5500.setIPAddress(local_ip.raw_address());
|
||||
w5500.setGatewayIp(gateway.raw_address());
|
||||
w5500.setSubnetMask(subnet.raw_address());
|
||||
_dnsServerAddress = dns_server;
|
||||
}
|
||||
#else
|
||||
int EthernetClass::begin(uint8_t *mac_address)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac_address, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
if (_dhcp != NULL) {
|
||||
delete _dhcp;
|
||||
}
|
||||
_dhcp = new DhcpClass();
|
||||
// Initialise the basic info
|
||||
w5500.init(w5500_cspin);
|
||||
w5500.setMACAddress(mac_address);
|
||||
w5500.setIPAddress(IPAddress(0,0,0,0).raw_address());
|
||||
|
||||
// Now try to get our config info from a DHCP server
|
||||
int ret = _dhcp->beginWithDHCP(mac_address);
|
||||
if(ret == 1)
|
||||
{
|
||||
// We've successfully found a DHCP server and got our configuration info, so set things
|
||||
// accordingly
|
||||
w5500.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
w5500.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
w5500.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
_dnsDomainName = _dhcp->getDnsDomainName();
|
||||
_hostName = _dhcp->getHostName();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac_address, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
// Assume the DNS server will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress dns_server = local_ip;
|
||||
dns_server[3] = 1;
|
||||
begin(mac_address, local_ip, dns_server);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac_address, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
// Assume the gateway will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress gateway = local_ip;
|
||||
gateway[3] = 1;
|
||||
begin(mac_address, local_ip, dns_server, gateway);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac_address, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
begin(mac_address, local_ip, dns_server, gateway, subnet);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac_address, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
w5500.init(w5500_cspin);
|
||||
w5500.setMACAddress(mac_address);
|
||||
w5500.setIPAddress(local_ip.raw_address());
|
||||
w5500.setGatewayIp(gateway.raw_address());
|
||||
w5500.setSubnetMask(subnet.raw_address());
|
||||
_dnsServerAddress = dns_server;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int EthernetClass::maintain(){
|
||||
int rc = DHCP_CHECK_NONE;
|
||||
if(_dhcp != NULL){
|
||||
//we have a pointer to dhcp, use it
|
||||
rc = _dhcp->checkLease();
|
||||
switch ( rc ){
|
||||
case DHCP_CHECK_NONE:
|
||||
//nothing done
|
||||
break;
|
||||
case DHCP_CHECK_RENEW_OK:
|
||||
case DHCP_CHECK_REBIND_OK:
|
||||
//we might have got a new IP.
|
||||
w5500.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
w5500.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
w5500.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
_dnsDomainName = _dhcp->getDnsDomainName();
|
||||
_hostName = _dhcp->getHostName();
|
||||
break;
|
||||
default:
|
||||
//this is actually a error, it will retry though
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
// KH add to report link status
|
||||
uint8_t EthernetClass::link()
|
||||
{
|
||||
return bitRead(w5500.getPHYCFGR(), 0);
|
||||
}
|
||||
|
||||
const char* EthernetClass::linkReport()
|
||||
{
|
||||
if (bitRead(w5500.getPHYCFGR(), 0) == 1)
|
||||
return "LINK";
|
||||
else
|
||||
return "NO LINK";
|
||||
}
|
||||
//////
|
||||
|
||||
IPAddress EthernetClass::localIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
w5500.getIPAddress(ret.raw_address());
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::subnetMask()
|
||||
{
|
||||
IPAddress ret;
|
||||
w5500.getSubnetMask(ret.raw_address());
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::gatewayIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
w5500.getGatewayIp(ret.raw_address());
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::dnsServerIP()
|
||||
{
|
||||
return _dnsServerAddress;
|
||||
}
|
||||
|
||||
char* EthernetClass::dnsDomainName(){
|
||||
return _dnsDomainName;
|
||||
}
|
||||
|
||||
char* EthernetClass::hostName(){
|
||||
return _hostName;
|
||||
}
|
||||
|
||||
EthernetClass Ethernet;
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
modified 12 Aug 2013
|
||||
by Soohwan Kim (suhwan@wiznet.co.kr)
|
||||
|
||||
- 10 Apr. 2015
|
||||
Added support for Arduino Ethernet Shield 2
|
||||
by Arduino.org team
|
||||
|
||||
*/
|
||||
#ifndef ethernet_h
|
||||
#define ethernet_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "utility/w5500.h"
|
||||
#include "IPAddress.h"
|
||||
#include "EthernetClient.h"
|
||||
#include "EthernetServer.h"
|
||||
#include "Dhcp.h"
|
||||
|
||||
|
||||
|
||||
class EthernetClass {
|
||||
private:
|
||||
IPAddress _dnsServerAddress;
|
||||
char* _dnsDomainName;
|
||||
char* _hostName;
|
||||
DhcpClass* _dhcp;
|
||||
|
||||
// KH add to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
uint8_t _mac_address[6] ={0,};
|
||||
//////
|
||||
|
||||
public:
|
||||
uint8_t w5500_cspin;
|
||||
|
||||
static uint8_t _state[MAX_SOCK_NUM];
|
||||
static uint16_t _server_port[MAX_SOCK_NUM];
|
||||
|
||||
EthernetClass() { _dhcp = NULL; w5500_cspin = 10; }
|
||||
void init(uint8_t _cspin = 10) { w5500_cspin = _cspin; }
|
||||
|
||||
#if defined(WIZ550io_WITH_MACADDRESS)
|
||||
// Initialize function when use the ioShield serise (included WIZ550io)
|
||||
// WIZ550io has a MAC address which is written after reset.
|
||||
// Default IP, Gateway and subnet address are also writen.
|
||||
// so, It needs some initial time. please refer WIZ550io Datasheet in details.
|
||||
int begin(void);
|
||||
void begin(IPAddress local_ip);
|
||||
void begin(IPAddress local_ip, IPAddress dns_server);
|
||||
void begin(IPAddress local_ip, IPAddress dns_server, IPAddress gateway);
|
||||
void begin(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet);
|
||||
#else
|
||||
// Initialize the Ethernet shield to use the provided MAC address and gain the rest of the
|
||||
// configuration through DHCP.
|
||||
// Returns 0 if the DHCP configuration failed, and 1 if it succeeded
|
||||
int begin(uint8_t *mac_address);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet);
|
||||
|
||||
#endif
|
||||
|
||||
int maintain();
|
||||
|
||||
// KH add to report link status
|
||||
uint8_t link(); // returns the linkstate, 1 = linked, 0 = no link
|
||||
const char* linkReport(); // returns the linkstate as a string
|
||||
//////
|
||||
|
||||
// KH add to have similar function to Ethernet lib
|
||||
// Certainly we can use void macAddress(uint8_t mac[]) to read from W5x00.
|
||||
void MACAddress(uint8_t *mac_address)
|
||||
{
|
||||
memcpy(mac_address, _mac_address, sizeof(_mac_address));
|
||||
}
|
||||
//////
|
||||
|
||||
IPAddress localIP();
|
||||
IPAddress subnetMask();
|
||||
IPAddress gatewayIP();
|
||||
IPAddress dnsServerIP();
|
||||
char* dnsDomainName();
|
||||
char* hostName();
|
||||
|
||||
friend class EthernetClient;
|
||||
friend class EthernetServer;
|
||||
};
|
||||
|
||||
extern EthernetClass Ethernet;
|
||||
|
||||
#endif
|
@ -0,0 +1,290 @@
|
||||
/*
|
||||
* Udp.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
|
||||
* This version only offers minimal wrapping of socket.c/socket.h
|
||||
* Drop Udp.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2008 Bjoern Hartmann
|
||||
* 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:
|
||||
*
|
||||
* The above copyright notice and 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.
|
||||
*
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*
|
||||
* - 10 Apr. 2015
|
||||
* Added support for Arduino Ethernet Shield 2
|
||||
* by Arduino.org team
|
||||
*/
|
||||
|
||||
#include "utility/w5500.h"
|
||||
#include "utility/socket.h"
|
||||
#include "Ethernet2.h"
|
||||
#include "Udp.h"
|
||||
#include "Dns.h"
|
||||
|
||||
#define ETHERNET2_DEBUG 0
|
||||
|
||||
/* Constructor */
|
||||
EthernetUDP::EthernetUDP() : _sock(MAX_SOCK_NUM) {}
|
||||
|
||||
/* Start EthernetUDP socket, listening at local port PORT */
|
||||
uint8_t EthernetUDP::begin(uint16_t port) {
|
||||
if (_sock != MAX_SOCK_NUM)
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < MAX_SOCK_NUM; i++) {
|
||||
uint8_t s = w5500.readSnSR(i);
|
||||
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
|
||||
_sock = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_sock == MAX_SOCK_NUM)
|
||||
return 0;
|
||||
|
||||
_port = port;
|
||||
_remaining = 0;
|
||||
socket(_sock, SnMR::UDP, _port, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//KH, to add Multicast support
|
||||
/* Start EthernetUDP socket, listening at local port PORT */
|
||||
uint8_t EthernetUDP::beginMulticast(IPAddress ip, uint16_t port)
|
||||
{
|
||||
if (_sock != MAX_SOCK_NUM)
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < MAX_SOCK_NUM; i++) {
|
||||
uint8_t s = w5500.readSnSR(i);
|
||||
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
|
||||
_sock = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_sock == MAX_SOCK_NUM)
|
||||
return 0;
|
||||
|
||||
// Calculate MAC address from Multicast IP Address
|
||||
byte mac[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 };
|
||||
|
||||
mac[3] = ip[1] & 0x7F;
|
||||
mac[4] = ip[2];
|
||||
mac[5] = ip[3];
|
||||
|
||||
w5500.writeSnDIPR(_sock, rawIPAddress(ip)); //239.255.0.1
|
||||
w5500.writeSnDPORT(_sock, port);
|
||||
w5500.writeSnDHAR(_sock,mac);
|
||||
|
||||
_remaining = 0;
|
||||
socket(_sock, SnMR::UDP, port, SnMR::MULTI);
|
||||
return 1;
|
||||
}
|
||||
//////
|
||||
|
||||
|
||||
|
||||
/* return number of bytes available in the current packet,
|
||||
will return zero if parsePacket hasn't been called yet */
|
||||
int EthernetUDP::available() {
|
||||
return _remaining;
|
||||
}
|
||||
|
||||
/* Release any resources being used by this EthernetUDP instance */
|
||||
void EthernetUDP::stop()
|
||||
{
|
||||
if (_sock == MAX_SOCK_NUM)
|
||||
return;
|
||||
|
||||
close(_sock);
|
||||
|
||||
EthernetClass::_server_port[_sock] = 0;
|
||||
_sock = MAX_SOCK_NUM;
|
||||
}
|
||||
|
||||
int EthernetUDP::beginPacket(const char *host, uint16_t port)
|
||||
{
|
||||
// Look up the host first
|
||||
int ret = 0;
|
||||
DNSClient dns;
|
||||
IPAddress remote_addr;
|
||||
|
||||
dns.begin(Ethernet.dnsServerIP());
|
||||
ret = dns.getHostByName(host, remote_addr);
|
||||
if (ret == 1) {
|
||||
return beginPacket(remote_addr, port);
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
int EthernetUDP::beginPacket(IPAddress ip, uint16_t port)
|
||||
{
|
||||
_offset = 0;
|
||||
|
||||
// KH debug
|
||||
#if (ETHERNET2_DEBUG > 1)
|
||||
Serial.print("Ethernet2UDP::beginPacket: ip=");
|
||||
Serial.print(ip);
|
||||
Serial.print(", port=");
|
||||
Serial.println(port);
|
||||
#endif
|
||||
|
||||
return startUDP(_sock, rawIPAddress(ip), port);
|
||||
}
|
||||
|
||||
int EthernetUDP::endPacket()
|
||||
{
|
||||
return sendUDP(_sock);
|
||||
}
|
||||
|
||||
size_t EthernetUDP::write(uint8_t byte)
|
||||
{
|
||||
return write(&byte, 1);
|
||||
}
|
||||
|
||||
size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
// KH debug
|
||||
#if (ETHERNET2_DEBUG > 1)
|
||||
Serial.print("Ethernet2UDP:write, size=");
|
||||
Serial.println(size);
|
||||
#endif
|
||||
|
||||
uint16_t bytes_written = bufferData(_sock, _offset, buffer, size);
|
||||
_offset += bytes_written;
|
||||
|
||||
// KH debug
|
||||
#if (ETHERNET2_DEBUG > 1)
|
||||
Serial.print("Ethernet2UDP: bytes written=");
|
||||
Serial.println(bytes_written);
|
||||
#endif
|
||||
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
int EthernetUDP::parsePacket()
|
||||
{
|
||||
// discard any remaining bytes in the last packet
|
||||
flush();
|
||||
|
||||
if (w5500.getRXReceivedSize(_sock) > 0)
|
||||
{
|
||||
//HACK - hand-parse the UDP packet using TCP recv method
|
||||
uint8_t tmpBuf[8];
|
||||
int ret =0;
|
||||
//read 8 header bytes and get IP and port from it
|
||||
ret = recv(_sock,tmpBuf,8);
|
||||
if (ret > 0)
|
||||
{
|
||||
_remoteIP = tmpBuf;
|
||||
_remotePort = tmpBuf[4];
|
||||
_remotePort = (_remotePort << 8) + tmpBuf[5];
|
||||
_remaining = tmpBuf[6];
|
||||
_remaining = (_remaining << 8) + tmpBuf[7];
|
||||
|
||||
// When we get here, any remaining bytes are the data
|
||||
ret = _remaining;
|
||||
}
|
||||
|
||||
// KH debug
|
||||
#if (ETHERNET2_DEBUG > 1)
|
||||
Serial.print("Ethernet2UDP:parsePacket OK, datasize=");
|
||||
Serial.println(ret);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
// There aren't any packets available
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EthernetUDP::read()
|
||||
{
|
||||
uint8_t byte;
|
||||
|
||||
if ((_remaining > 0) && (recv(_sock, &byte, 1) > 0))
|
||||
{
|
||||
// We read things without any problems
|
||||
_remaining--;
|
||||
return byte;
|
||||
}
|
||||
|
||||
// If we get here, there's no data available
|
||||
return -1;
|
||||
}
|
||||
|
||||
int EthernetUDP::read(unsigned char* buffer, size_t len)
|
||||
{
|
||||
|
||||
if (_remaining > 0)
|
||||
{
|
||||
|
||||
int got;
|
||||
|
||||
if (_remaining <= len)
|
||||
{
|
||||
// data should fit in the buffer
|
||||
got = recv(_sock, buffer, _remaining);
|
||||
}
|
||||
else
|
||||
{
|
||||
// too much data for the buffer,
|
||||
// grab as much as will fit
|
||||
got = recv(_sock, buffer, len);
|
||||
}
|
||||
|
||||
if (got > 0)
|
||||
{
|
||||
_remaining -= got;
|
||||
return got;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If we get here, there's no data available or recv failed
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
int EthernetUDP::peek()
|
||||
{
|
||||
uint8_t b;
|
||||
// Unlike recv, peek doesn't check to see if there's any data available, so we must.
|
||||
// If the user hasn't called parsePacket yet then return nothing otherwise they
|
||||
// may get the UDP header
|
||||
if (!_remaining)
|
||||
return -1;
|
||||
::peek(_sock, &b);
|
||||
return b;
|
||||
}
|
||||
|
||||
void EthernetUDP::flush()
|
||||
{
|
||||
// could this fail (loop endlessly) if _remaining > 0 and recv in read fails?
|
||||
// should only occur if recv fails after telling us the data is there, lets
|
||||
// hope the w5500 always behaves :)
|
||||
|
||||
while (_remaining)
|
||||
{
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Udp.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
|
||||
* This version only offers minimal wrapping of socket.c/socket.h
|
||||
* Drop Udp.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
|
||||
*
|
||||
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
|
||||
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
|
||||
* might not happen often in practice, but in larger network topologies, a UDP
|
||||
* packet can be received out of sequence.
|
||||
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
|
||||
* aware of it. Again, this may not be a concern in practice on small local networks.
|
||||
* For more information, see http://www.cafeaulait.org/course/week12/35.html
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2008 Bjoern Hartmann
|
||||
* 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:
|
||||
*
|
||||
* The above copyright notice and 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.
|
||||
*
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*
|
||||
* - 10 Apr. 2015
|
||||
* Added support for Arduino Ethernet Shield 2
|
||||
* by Arduino.org team
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ethernetudp_h
|
||||
#define ethernetudp_h
|
||||
|
||||
#include <Udp.h>
|
||||
|
||||
#define UDP_TX_PACKET_MAX_SIZE 24
|
||||
|
||||
class EthernetUDP : public UDP {
|
||||
private:
|
||||
uint8_t _sock; // socket ID for Wiz5100
|
||||
uint16_t _port; // local port to listen on
|
||||
IPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed
|
||||
uint16_t _remotePort; // remote port for the incoming packet whilst it's being processed
|
||||
uint16_t _offset; // offset into the packet being sent
|
||||
uint16_t _remaining; // remaining bytes of incoming packet yet to be processed
|
||||
|
||||
public:
|
||||
EthernetUDP(); // Constructor
|
||||
virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
|
||||
|
||||
//KH, to add Multicast support
|
||||
virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
|
||||
//////
|
||||
|
||||
virtual void stop(); // Finish with the UDP socket
|
||||
|
||||
// Sending UDP packets
|
||||
|
||||
// Start building up a packet to send to the remote host specific in ip and port
|
||||
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
|
||||
virtual int beginPacket(IPAddress ip, uint16_t port);
|
||||
// Start building up a packet to send to the remote host specific in host and port
|
||||
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
|
||||
virtual int beginPacket(const char *host, uint16_t port);
|
||||
// Finish off this packet and send it
|
||||
// Returns 1 if the packet was sent successfully, 0 if there was an error
|
||||
virtual int endPacket();
|
||||
// Write a single byte into the packet
|
||||
virtual size_t write(uint8_t);
|
||||
// Write size bytes from buffer into the packet
|
||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||
|
||||
using Print::write;
|
||||
|
||||
// Start processing the next available incoming packet
|
||||
// Returns the size of the packet in bytes, or 0 if no packets are available
|
||||
virtual int parsePacket();
|
||||
// Number of bytes remaining in the current packet
|
||||
virtual int available();
|
||||
// Read a single byte from the current packet
|
||||
virtual int read();
|
||||
// Read up to len bytes from the current packet and place them into buffer
|
||||
// Returns the number of bytes read, or 0 if none are available
|
||||
virtual int read(unsigned char* buffer, size_t len);
|
||||
// Read up to len characters from the current packet and place them into buffer
|
||||
// Returns the number of characters read, or 0 if none are available
|
||||
virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
|
||||
// Return the next byte from the current packet without moving on to the next byte
|
||||
virtual int peek();
|
||||
virtual void flush(); // Finish reading the current packet
|
||||
|
||||
// Return the IP address of the host who sent the current incoming packet
|
||||
virtual IPAddress remoteIP() { return _remoteIP; };
|
||||
// Return the port of the host who sent the current incoming packet
|
||||
virtual uint16_t remotePort() { return _remotePort; };
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,431 @@
|
||||
/*
|
||||
modified 12 Aug 2013
|
||||
by Soohwan Kim (suhwan@wiznet.co.kr)
|
||||
|
||||
- 10 Apr. 2015
|
||||
Added support for Arduino Ethernet Shield 2
|
||||
by Arduino.org team
|
||||
|
||||
*/
|
||||
|
||||
#include "Ethernet3.h"
|
||||
#include "Dhcp.h"
|
||||
|
||||
// XXX: don't make assumptions about the value of MAX_SOCK_NUM.
|
||||
uint8_t EthernetClass::_state[MAX_SOCK_NUM] = { 0, };
|
||||
uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = { 0, };
|
||||
|
||||
void EthernetClass::setRstPin(uint8_t pinRST) {
|
||||
_pinRST = pinRST;
|
||||
pinMode(_pinRST, OUTPUT);
|
||||
digitalWrite(_pinRST, HIGH);
|
||||
}
|
||||
void EthernetClass::setCsPin(uint8_t pinCS) {
|
||||
_pinCS = pinCS;
|
||||
}
|
||||
|
||||
void EthernetClass::init(uint8_t maxSockNum) {
|
||||
_maxSockNum = maxSockNum;
|
||||
}
|
||||
|
||||
uint8_t EthernetClass::softreset() {
|
||||
return w5500.softReset();
|
||||
}
|
||||
|
||||
void EthernetClass::hardreset() {
|
||||
if(_pinRST != 0) {
|
||||
digitalWrite(_pinRST, LOW);
|
||||
delay(1);
|
||||
digitalWrite(_pinRST, HIGH);
|
||||
delay(150);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WIZ550io_WITH_MACADDRESS)
|
||||
|
||||
int EthernetClass::begin(void)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var _mac_address
|
||||
//uint8_t mac_address[6] ={0,};
|
||||
//////
|
||||
|
||||
_dhcp = new DhcpClass();
|
||||
|
||||
// Initialise the basic info
|
||||
w5500.init(_maxSockNum, _pinCS);
|
||||
w5500.setIPAddress(IPAddress(0,0,0,0).raw_address());
|
||||
|
||||
// KH mod
|
||||
w5500.getMACAddress(_mac_address);
|
||||
//////
|
||||
|
||||
if (strlen(_customHostname) != 0)
|
||||
{
|
||||
_dhcp->setCustomHostname(_customHostname);
|
||||
}
|
||||
|
||||
// Now try to get our config info from a DHCP server
|
||||
// KH mod
|
||||
int ret = _dhcp->beginWithDHCP(_mac_address);
|
||||
//////
|
||||
|
||||
if(ret == 1)
|
||||
{
|
||||
// We've successfully found a DHCP server and got our configuration info, so set things
|
||||
// accordingly
|
||||
w5500.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
w5500.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
w5500.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EthernetClass::begin(IPAddress local_ip)
|
||||
{
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
begin(local_ip, subnet);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(IPAddress local_ip, IPAddress subnet)
|
||||
{
|
||||
// Assume the gateway will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress gateway = local_ip;
|
||||
gateway[3] = 1;
|
||||
begin(local_ip, subnet, gateway);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(IPAddress local_ip, IPAddress subnet, IPAddress gateway)
|
||||
{
|
||||
// Assume the DNS server will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress dns_server = local_ip;
|
||||
dns_server[3] = 1;
|
||||
begin(local_ip, subnet, gateway, dns_server);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(IPAddress local_ip, IPAddress subnet, IPAddress gateway, IPAddress dns_server)
|
||||
{
|
||||
w5500.init(_maxSockNum, _pinCS);
|
||||
w5500.setIPAddress(local_ip.raw_address());
|
||||
w5500.setGatewayIp(gateway.raw_address());
|
||||
w5500.setSubnetMask(subnet.raw_address());
|
||||
_dnsServerAddress = dns_server;
|
||||
}
|
||||
|
||||
#else
|
||||
int EthernetClass::begin(uint8_t *mac_address)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac_address, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
_dhcp = new DhcpClass();
|
||||
// Initialise the basic info
|
||||
w5500.init(_maxSockNum, _pinCS);
|
||||
w5500.setMACAddress(mac_address);
|
||||
w5500.setIPAddress(IPAddress(0,0,0,0).raw_address());
|
||||
|
||||
if (strlen(_customHostname) != 0)
|
||||
{
|
||||
_dhcp->setCustomHostname(_customHostname);
|
||||
}
|
||||
|
||||
// Now try to get our config info from a DHCP server
|
||||
int ret = _dhcp->beginWithDHCP(mac_address);
|
||||
if(ret == 1)
|
||||
{
|
||||
// We've successfully found a DHCP server and got our configuration info, so set things
|
||||
// accordingly
|
||||
w5500.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
w5500.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
w5500.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac_address, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
begin(mac_address, local_ip, subnet);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress subnet)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac_address, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
// Assume the gateway will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress gateway = local_ip;
|
||||
gateway[3] = 1;
|
||||
begin(mac_address, local_ip, subnet, gateway);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress subnet, IPAddress gateway)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac_address, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
// Assume the DNS server will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress dns_server = local_ip;
|
||||
dns_server[3] = 1;
|
||||
begin(mac_address, local_ip, subnet, gateway, dns_server);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress subnet, IPAddress gateway, IPAddress dns_server)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac_address, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
w5500.init(_maxSockNum, _pinCS);
|
||||
w5500.setMACAddress(mac_address);
|
||||
w5500.setIPAddress(local_ip.raw_address());
|
||||
w5500.setGatewayIp(gateway.raw_address());
|
||||
w5500.setSubnetMask(subnet.raw_address());
|
||||
_dnsServerAddress = dns_server;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int EthernetClass::maintain(){
|
||||
int rc = DHCP_CHECK_NONE;
|
||||
if(_dhcp != NULL){
|
||||
//we have a pointer to dhcp, use it
|
||||
rc = _dhcp->checkLease();
|
||||
switch ( rc ){
|
||||
case DHCP_CHECK_NONE:
|
||||
//nothing done
|
||||
break;
|
||||
case DHCP_CHECK_RENEW_OK:
|
||||
case DHCP_CHECK_REBIND_OK:
|
||||
//we might have got a new IP.
|
||||
w5500.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
w5500.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
w5500.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
break;
|
||||
default:
|
||||
//this is actually a error, it will retry though
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void EthernetClass::WoL(bool wol) {
|
||||
uint8_t val = w5500.readMR();
|
||||
bitWrite(val, 5, wol);
|
||||
w5500.writeMR(val);
|
||||
}
|
||||
|
||||
bool EthernetClass::WoL() {
|
||||
uint8_t val = w5500.readMR();
|
||||
return bitRead(val, 5);
|
||||
}
|
||||
|
||||
void EthernetClass::phyMode(phyMode_t mode) {
|
||||
uint8_t val = w5500.getPHYCFGR();
|
||||
bitWrite(val, 6, 1);
|
||||
if (mode == HALF_DUPLEX_10) {
|
||||
bitWrite(val, 3, 0);
|
||||
bitWrite(val, 4, 0);
|
||||
bitWrite(val, 5, 0);
|
||||
w5500.setPHYCFGR(val);
|
||||
}
|
||||
else if (mode == FULL_DUPLEX_10) {
|
||||
bitWrite(val, 3, 1);
|
||||
bitWrite(val, 4, 0);
|
||||
bitWrite(val, 5, 0);
|
||||
w5500.setPHYCFGR(val);
|
||||
}
|
||||
else if (mode == HALF_DUPLEX_100) {
|
||||
bitWrite(val, 3, 0);
|
||||
bitWrite(val, 4, 1);
|
||||
bitWrite(val, 5, 0);
|
||||
w5500.setPHYCFGR(val);
|
||||
}
|
||||
else if (mode == FULL_DUPLEX_100) {
|
||||
bitWrite(val, 3, 1);
|
||||
bitWrite(val, 4, 1);
|
||||
bitWrite(val, 5, 0);
|
||||
w5500.setPHYCFGR(val);
|
||||
}
|
||||
else if (mode == FULL_DUPLEX_100_AUTONEG) {
|
||||
bitWrite(val, 3, 0);
|
||||
bitWrite(val, 4, 0);
|
||||
bitWrite(val, 5, 1);
|
||||
w5500.setPHYCFGR(val);
|
||||
}
|
||||
else if (mode == POWER_DOWN) {
|
||||
bitWrite(val, 3, 0);
|
||||
bitWrite(val, 4, 1);
|
||||
bitWrite(val, 5, 1);
|
||||
w5500.setPHYCFGR(val);
|
||||
}
|
||||
else if (mode == ALL_AUTONEG) {
|
||||
bitWrite(val, 3, 1);
|
||||
bitWrite(val, 4, 1);
|
||||
bitWrite(val, 5, 1);
|
||||
w5500.setPHYCFGR(val);
|
||||
}
|
||||
bitWrite(val, 7, 0);
|
||||
w5500.setPHYCFGR(val);
|
||||
bitWrite(val, 7, 1);
|
||||
w5500.setPHYCFGR(val);
|
||||
}
|
||||
|
||||
void EthernetClass::setHostname(const char* hostname) {
|
||||
memset(_customHostname, 0, 32);
|
||||
memcpy((void*)_customHostname, (void*)hostname, strlen(hostname) >= 31 ? 31 : strlen(hostname));
|
||||
}
|
||||
|
||||
uint8_t EthernetClass::phyState() {
|
||||
return w5500.getPHYCFGR();
|
||||
}
|
||||
|
||||
uint8_t EthernetClass::link() {
|
||||
return bitRead(w5500.getPHYCFGR(), 0);
|
||||
}
|
||||
|
||||
const char* EthernetClass::linkReport()
|
||||
{
|
||||
if (bitRead(w5500.getPHYCFGR(), 0) == 1)
|
||||
return "LINK";
|
||||
else
|
||||
return "NO LINK";
|
||||
}
|
||||
|
||||
uint8_t EthernetClass::speed()
|
||||
{
|
||||
if (bitRead(w5500.getPHYCFGR(), 0) == 1)
|
||||
{
|
||||
if (bitRead(w5500.getPHYCFGR(), 1) == 1)
|
||||
return 100;
|
||||
|
||||
if (bitRead(w5500.getPHYCFGR(), 1) == 0)
|
||||
return 10;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* EthernetClass::speedReport()
|
||||
{
|
||||
if (bitRead(w5500.getPHYCFGR(), 0) == 1)
|
||||
{
|
||||
if (bitRead(w5500.getPHYCFGR(), 1) == 1)
|
||||
return "100 MB";
|
||||
|
||||
if (bitRead(w5500.getPHYCFGR(), 1) == 0)
|
||||
return "10 MB";
|
||||
}
|
||||
|
||||
return "NO LINK";
|
||||
}
|
||||
|
||||
uint8_t EthernetClass::duplex()
|
||||
{
|
||||
if(bitRead(w5500.getPHYCFGR(), 0) == 1)
|
||||
{
|
||||
if (bitRead(w5500.getPHYCFGR(), 2) == 1)
|
||||
return 2;
|
||||
|
||||
if (bitRead(w5500.getPHYCFGR(), 2) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* EthernetClass::duplexReport()
|
||||
{
|
||||
if (bitRead(w5500.getPHYCFGR(), 0) == 1)
|
||||
{
|
||||
if(bitRead(w5500.getPHYCFGR(), 2) == 1)
|
||||
return "FULL DUPLEX";
|
||||
|
||||
if (bitRead(w5500.getPHYCFGR(), 2) == 0)
|
||||
return "HALF DUPLEX";
|
||||
}
|
||||
|
||||
return "NO LINK";
|
||||
}
|
||||
|
||||
void EthernetClass::setRtTimeOut(uint16_t timeout) {
|
||||
w5500.setRetransmissionTime(timeout);
|
||||
}
|
||||
|
||||
uint16_t EthernetClass::getRtTimeOut() {
|
||||
return w5500.getRetransmissionTime();
|
||||
}
|
||||
|
||||
void EthernetClass::setRtCount(uint8_t count) {
|
||||
w5500.setRetransmissionCount(count);
|
||||
}
|
||||
|
||||
uint8_t EthernetClass::getRtCount() {
|
||||
return w5500.getRetransmissionCount();
|
||||
}
|
||||
|
||||
void EthernetClass::macAddress(uint8_t mac[]) {
|
||||
w5500.getMACAddress(mac);
|
||||
}
|
||||
|
||||
const char* EthernetClass::macAddressReport() {
|
||||
uint8_t mac[6];
|
||||
static char str[18];
|
||||
w5500.getMACAddress(mac);
|
||||
sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
return str;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::localIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
w5500.getIPAddress(ret.raw_address());
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::subnetMask()
|
||||
{
|
||||
IPAddress ret;
|
||||
w5500.getSubnetMask(ret.raw_address());
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::gatewayIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
w5500.getGatewayIp(ret.raw_address());
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::dnsServerIP()
|
||||
{
|
||||
return _dnsServerAddress;
|
||||
}
|
||||
|
||||
EthernetClass Ethernet;
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
modified 12 Aug 2013
|
||||
by Soohwan Kim (suhwan@wiznet.co.kr)
|
||||
|
||||
- 10 Apr. 2015
|
||||
Added support for Arduino Ethernet Shield 2
|
||||
by Arduino.org team
|
||||
|
||||
*/
|
||||
#ifndef ethernet3_h
|
||||
#define ethernet3_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "utility/w5500.h"
|
||||
#include "IPAddress.h"
|
||||
#include "EthernetClient.h"
|
||||
#include "EthernetServer.h"
|
||||
#include "Dhcp.h"
|
||||
|
||||
enum phyMode_t {
|
||||
HALF_DUPLEX_10,
|
||||
FULL_DUPLEX_10,
|
||||
HALF_DUPLEX_100,
|
||||
FULL_DUPLEX_100,
|
||||
FULL_DUPLEX_100_AUTONEG,
|
||||
POWER_DOWN,
|
||||
ALL_AUTONEG
|
||||
};
|
||||
|
||||
class EthernetClass {
|
||||
private:
|
||||
IPAddress _dnsServerAddress;
|
||||
DhcpClass* _dhcp;
|
||||
char _customHostname[32];
|
||||
|
||||
// KH add to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
uint8_t _mac_address[6] ={0,};
|
||||
//////
|
||||
|
||||
public:
|
||||
uint8_t _maxSockNum;
|
||||
uint8_t _pinCS;
|
||||
uint8_t _pinRST;
|
||||
|
||||
static uint8_t _state[MAX_SOCK_NUM];
|
||||
static uint16_t _server_port[MAX_SOCK_NUM];
|
||||
|
||||
EthernetClass() { _dhcp = NULL; _pinCS = 10; _maxSockNum = 8; }
|
||||
|
||||
void setRstPin(uint8_t pinRST = 9); // for WIZ550io or USR-ES1, must set befor Ethernet.begin
|
||||
void setCsPin(uint8_t pinCS = 10); // must set befor Ethernet.begin
|
||||
|
||||
// Initialize with less sockets but more RX/TX Buffer
|
||||
// maxSockNum = 1 Socket 0 -> RX/TX Buffer 16k
|
||||
// maxSockNum = 2 Socket 0, 1 -> RX/TX Buffer 8k
|
||||
// maxSockNum = 4 Socket 0...3 -> RX/TX Buffer 4k
|
||||
// maxSockNum = 8 (Standard) all sockets -> RX/TX Buffer 2k
|
||||
// be carefull of the MAX_SOCK_NUM, because in the moment it can't dynamicly changed
|
||||
void init(uint8_t maxSockNum = 8);
|
||||
|
||||
uint8_t softreset(); // can set only after Ethernet.begin
|
||||
void hardreset(); // You need to set the Rst pin
|
||||
|
||||
#if defined(WIZ550io_WITH_MACADDRESS)
|
||||
|
||||
// Initialize function when use the ioShield serise (included WIZ550io)
|
||||
// WIZ550io has a MAC address which is written after reset.
|
||||
// Default IP, Gateway and subnet address are also writen.
|
||||
// so, It needs some initial time. please refer WIZ550io Datasheet in details.
|
||||
int begin(void);
|
||||
void begin(IPAddress local_ip);
|
||||
void begin(IPAddress local_ip, IPAddress subnet);
|
||||
void begin(IPAddress local_ip, IPAddress subnet, IPAddress gateway);
|
||||
void begin(IPAddress local_ip, IPAddress subnet, IPAddress gateway, IPAddress dns_server);
|
||||
#else
|
||||
// Initialize the Ethernet shield to use the provided MAC address and gain the rest of the
|
||||
// configuration through DHCP.
|
||||
// Returns 0 if the DHCP configuration failed, and 1 if it succeeded
|
||||
int begin(uint8_t *mac_address);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress subnet);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress subnet, IPAddress gateway);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress subnet, IPAddress gateway, IPAddress dns_server);
|
||||
#endif
|
||||
|
||||
int maintain();
|
||||
void WoL(bool wol); // set Wake on LAN
|
||||
bool WoL(); // get the WoL state
|
||||
void phyMode(phyMode_t mode); // set PHYCFGR
|
||||
uint8_t phyState(); // returns the PHYCFGR
|
||||
uint8_t link(); // returns the linkstate, 1 = linked, 0 = no link
|
||||
const char* linkReport(); // returns the linkstate as a string
|
||||
uint8_t speed(); // returns speed in MB/s
|
||||
const char* speedReport(); // returns speed as a string
|
||||
uint8_t duplex(); // returns duplex mode 0 = no link, 1 = Half Duplex, 2 = Full Duplex
|
||||
const char* duplexReport(); // returns duplex mode as a string
|
||||
|
||||
void setRtTimeOut(uint16_t timeout = 2000); // set the retransmission timout *100us
|
||||
uint16_t getRtTimeOut(); // get the retransmission timout
|
||||
void setRtCount(uint8_t count = 8); // set the retransmission count
|
||||
uint8_t getRtCount(); // get the retransmission count
|
||||
|
||||
void macAddress(uint8_t mac[]); // get the MAC Address
|
||||
const char* macAddressReport(); // returns the the MAC Address as a string
|
||||
|
||||
void setHostname(const char* hostname);
|
||||
|
||||
// KH add to have similar function to Ethernet lib
|
||||
// Certainly we can use void macAddress(uint8_t mac[]) to read from W5x00.
|
||||
void MACAddress(uint8_t *mac_address)
|
||||
{
|
||||
memcpy(mac_address, _mac_address, sizeof(_mac_address));
|
||||
}
|
||||
//////
|
||||
|
||||
IPAddress localIP();
|
||||
IPAddress subnetMask();
|
||||
IPAddress gatewayIP();
|
||||
IPAddress dnsServerIP();
|
||||
|
||||
friend class EthernetClient;
|
||||
friend class EthernetServer;
|
||||
};
|
||||
|
||||
extern EthernetClass Ethernet;
|
||||
|
||||
#endif
|
@ -0,0 +1,318 @@
|
||||
/****************************************************************************************************************************
|
||||
EthernetLarge.cpp
|
||||
|
||||
EthernetWebServer is a library for the Ethernet shields to run WebServer
|
||||
|
||||
Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer
|
||||
Licensed under MIT license
|
||||
Version: 1.0.9
|
||||
|
||||
Copyright 2018 Paul Stoffregen
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries
|
||||
1.0.1 K Hoang 20/02/2020 Add support to lambda functions
|
||||
1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60
|
||||
1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards
|
||||
1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards
|
||||
1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense,
|
||||
Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc.
|
||||
More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge
|
||||
1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards
|
||||
1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards
|
||||
1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards.
|
||||
1.0.9 K Hoang 15/05/2020 Add EthernetWrapper.h for easier W5x00 support as well as more Ethernet libs in the future.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "EthernetLarge.h"
|
||||
#include "utility/w5100.h"
|
||||
#include "Dhcp.h"
|
||||
|
||||
#define ETHERNET_DEBUG 1
|
||||
|
||||
IPAddress EthernetClass::_dnsServerAddress;
|
||||
DhcpClass* EthernetClass::_dhcp = NULL;
|
||||
|
||||
// KH
|
||||
void EthernetClass::setRstPin(uint8_t pinRST)
|
||||
{
|
||||
_pinRST = pinRST;
|
||||
pinMode(_pinRST, OUTPUT);
|
||||
digitalWrite(_pinRST, HIGH);
|
||||
}
|
||||
void EthernetClass::setCsPin(uint8_t pinCS)
|
||||
{
|
||||
_pinCS = pinCS;
|
||||
W5100.setSS(pinCS);
|
||||
|
||||
#if ( ETHERNET_DEBUG > 0 )
|
||||
Serial.print("Input pinCS = ");
|
||||
Serial.println(pinCS);
|
||||
Serial.print("_pinCS = ");
|
||||
Serial.println(_pinCS);
|
||||
#endif
|
||||
}
|
||||
|
||||
void EthernetClass::initMaxSockNum(uint8_t maxSockNum)
|
||||
{
|
||||
_maxSockNum = maxSockNum;
|
||||
}
|
||||
|
||||
uint8_t EthernetClass::softreset()
|
||||
{
|
||||
return W5100.softReset();
|
||||
}
|
||||
|
||||
void EthernetClass::hardreset()
|
||||
{
|
||||
if(_pinRST != 0)
|
||||
{
|
||||
digitalWrite(_pinRST, LOW);
|
||||
delay(1);
|
||||
digitalWrite(_pinRST, HIGH);
|
||||
delay(150);
|
||||
}
|
||||
}
|
||||
|
||||
int EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)
|
||||
{
|
||||
static DhcpClass s_dhcp;
|
||||
_dhcp = &s_dhcp;
|
||||
|
||||
#if ( ETHERNET_DEBUG > 0 )
|
||||
Serial.print("_pinCS = ");
|
||||
Serial.print(_pinCS);
|
||||
#endif
|
||||
|
||||
// Initialise the basic info
|
||||
if (W5100.init() == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setMACAddress(mac);
|
||||
W5100.setIPAddress(IPAddress(0,0,0,0).raw_address());
|
||||
SPI.endTransaction();
|
||||
|
||||
// Now try to get our config info from a DHCP server
|
||||
int ret = _dhcp->beginWithDHCP(mac, timeout, responseTimeout);
|
||||
if (ret == 1) {
|
||||
// We've successfully found a DHCP server and got our configuration
|
||||
// info, so set things accordingly
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
SPI.endTransaction();
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
socketPortRand(micros());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac, IPAddress ip)
|
||||
{
|
||||
// Assume the DNS server will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress dns = ip;
|
||||
dns[3] = 1;
|
||||
begin(mac, ip, dns);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns)
|
||||
{
|
||||
// Assume the gateway will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress gateway = ip;
|
||||
gateway[3] = 1;
|
||||
begin(mac, ip, dns, gateway);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway)
|
||||
{
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
begin(mac, ip, dns, gateway, subnet);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)
|
||||
{
|
||||
// Initialise the basic info
|
||||
if (W5100.init() == 0)
|
||||
return;
|
||||
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setMACAddress(mac);
|
||||
#if ( defined(ESP8266) || defined(ESP32) )
|
||||
W5100.setIPAddress(&ip[0]);
|
||||
W5100.setGatewayIp(&gateway[0]);
|
||||
W5100.setSubnetMask(&subnet[0]);
|
||||
#elif ARDUINO > 106 || TEENSYDUINO > 121
|
||||
W5100.setIPAddress(ip._address.bytes);
|
||||
W5100.setGatewayIp(gateway._address.bytes);
|
||||
W5100.setSubnetMask(subnet._address.bytes);
|
||||
#else
|
||||
W5100.setIPAddress(ip._address);
|
||||
W5100.setGatewayIp(gateway._address);
|
||||
W5100.setSubnetMask(subnet._address);
|
||||
#endif
|
||||
SPI.endTransaction();
|
||||
_dnsServerAddress = dns;
|
||||
}
|
||||
|
||||
void EthernetClass::init(uint8_t sspin)
|
||||
{
|
||||
W5100.setSS(sspin);
|
||||
}
|
||||
|
||||
EthernetLinkStatus EthernetClass::linkStatus()
|
||||
{
|
||||
switch (W5100.getLinkStatus()) {
|
||||
case UNKNOWN: return Unknown;
|
||||
case LINK_ON: return LinkON;
|
||||
case LINK_OFF: return LinkOFF;
|
||||
default: return Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
EthernetHardwareStatus EthernetClass::hardwareStatus()
|
||||
{
|
||||
switch (W5100.getChip()) {
|
||||
case 51: return EthernetW5100;
|
||||
case 52: return EthernetW5200;
|
||||
case 55: return EthernetW5500;
|
||||
default: return EthernetNoHardware;
|
||||
}
|
||||
}
|
||||
|
||||
int EthernetClass::maintain()
|
||||
{
|
||||
int rc = DHCP_CHECK_NONE;
|
||||
if (_dhcp != NULL) {
|
||||
// we have a pointer to dhcp, use it
|
||||
rc = _dhcp->checkLease();
|
||||
switch (rc)
|
||||
{
|
||||
case DHCP_CHECK_NONE:
|
||||
//nothing done
|
||||
break;
|
||||
case DHCP_CHECK_RENEW_OK:
|
||||
case DHCP_CHECK_REBIND_OK:
|
||||
//we might have got a new IP.
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
SPI.endTransaction();
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
break;
|
||||
default:
|
||||
//this is actually an error, it will retry though
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void EthernetClass::MACAddress(uint8_t *mac_address)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.getMACAddress(mac_address);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::localIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.getIPAddress(ret.raw_address());
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::subnetMask()
|
||||
{
|
||||
IPAddress ret;
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.getSubnetMask(ret.raw_address());
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::gatewayIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.getGatewayIp(ret.raw_address());
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EthernetClass::setMACAddress(const uint8_t *mac_address)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setMACAddress(mac_address);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void EthernetClass::setLocalIP(const IPAddress local_ip)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
IPAddress ip = local_ip;
|
||||
W5100.setIPAddress(ip.raw_address());
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void EthernetClass::setSubnetMask(const IPAddress subnet)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
IPAddress ip = subnet;
|
||||
W5100.setSubnetMask(ip.raw_address());
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void EthernetClass::setGatewayIP(const IPAddress gateway)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
IPAddress ip = gateway;
|
||||
W5100.setGatewayIp(ip.raw_address());
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void EthernetClass::setRetransmissionTimeout(uint16_t milliseconds)
|
||||
{
|
||||
if (milliseconds > 6553) milliseconds = 6553;
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setRetransmissionTime(milliseconds * 10);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void EthernetClass::setRetransmissionCount(uint8_t num)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setRetransmissionCount(num);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
|
||||
EthernetClass Ethernet;
|
@ -0,0 +1,362 @@
|
||||
/****************************************************************************************************************************
|
||||
EthernetLarge.h
|
||||
|
||||
EthernetWebServer is a library for the Ethernet shields to run WebServer
|
||||
|
||||
Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer
|
||||
Licensed under MIT license
|
||||
Version: 1.0.9
|
||||
|
||||
Copyright 2018 Paul Stoffregen
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries
|
||||
1.0.1 K Hoang 20/02/2020 Add support to lambda functions
|
||||
1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60
|
||||
1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards
|
||||
1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards
|
||||
1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense,
|
||||
Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc.
|
||||
More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge
|
||||
1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards
|
||||
1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards
|
||||
1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards.
|
||||
1.0.9 K Hoang 15/05/2020 Add EthernetWrapper.h for easier W5x00 support as well as more Ethernet libs in the future.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#ifndef ethernet_h_
|
||||
#define ethernet_h_
|
||||
|
||||
// All symbols exposed to Arduino sketches are contained in this header file
|
||||
//
|
||||
// Older versions had much of this stuff in EthernetClient.h, EthernetServer.h,
|
||||
// and socket.h. Including headers in different order could cause trouble, so
|
||||
// these "friend" classes are now defined in the same header file. socket.h
|
||||
// was removed to avoid possible conflict with the C library header files.
|
||||
|
||||
|
||||
// Configure the maximum number of sockets to support. W5100 chips can have
|
||||
// up to 4 sockets. W5200 & W5500 can have up to 8 sockets. Several bytes
|
||||
// of RAM are used for each socket. Reducing the maximum can save RAM, but
|
||||
// you are limited to fewer simultaneous connections.
|
||||
#define MAX_SOCK_NUM 2
|
||||
|
||||
// By default, each socket uses 2K buffers inside the Wiznet chip. If
|
||||
// MAX_SOCK_NUM is set to fewer than the chip's maximum, uncommenting
|
||||
// this will use larger buffers within the Wiznet chip. Large buffers
|
||||
// can really help with UDP protocols like Artnet. In theory larger
|
||||
// buffers should allow faster TCP over high-latency links, but this
|
||||
// does not always seem to work in practice (maybe Wiznet bugs?)
|
||||
#define ETHERNET_LARGE_BUFFERS
|
||||
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "Client.h"
|
||||
#include "Server.h"
|
||||
#include "Udp.h"
|
||||
|
||||
enum EthernetLinkStatus {
|
||||
Unknown,
|
||||
LinkON,
|
||||
LinkOFF
|
||||
};
|
||||
|
||||
enum EthernetHardwareStatus {
|
||||
EthernetNoHardware,
|
||||
EthernetW5100,
|
||||
EthernetW5200,
|
||||
EthernetW5500
|
||||
};
|
||||
|
||||
class EthernetUDP;
|
||||
class EthernetClient;
|
||||
class EthernetServer;
|
||||
class DhcpClass;
|
||||
|
||||
class EthernetClass {
|
||||
private:
|
||||
static IPAddress _dnsServerAddress;
|
||||
static DhcpClass* _dhcp;
|
||||
public:
|
||||
// KH
|
||||
uint8_t _maxSockNum;
|
||||
uint8_t _pinCS;
|
||||
uint8_t _pinRST;
|
||||
|
||||
void setRstPin(uint8_t pinRST = 9); // for WIZ550io or USR-ES1, must set befor Ethernet.begin
|
||||
void setCsPin(uint8_t pinCS = 10); // must set befor Ethernet.begin
|
||||
|
||||
// Initialize with less sockets but more RX/TX Buffer
|
||||
// maxSockNum = 1 Socket 0 -> RX/TX Buffer 16k
|
||||
// maxSockNum = 2 Socket 0, 1 -> RX/TX Buffer 8k
|
||||
// maxSockNum = 4 Socket 0...3 -> RX/TX Buffer 4k
|
||||
// maxSockNum = 8 (Standard) all sockets -> RX/TX Buffer 2k
|
||||
// be carefull of the MAX_SOCK_NUM, because in the moment it can't dynamicly changed
|
||||
void initMaxSockNum(uint8_t maxSockNum = 8);
|
||||
|
||||
uint8_t softreset(); // can set only after Ethernet.begin
|
||||
void hardreset(); // You need to set the Rst pin
|
||||
|
||||
// Initialise the Ethernet shield to use the provided MAC address and
|
||||
// gain the rest of the configuration through DHCP.
|
||||
// Returns 0 if the DHCP configuration failed, and 1 if it succeeded
|
||||
int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);
|
||||
int maintain();
|
||||
EthernetLinkStatus linkStatus();
|
||||
EthernetHardwareStatus hardwareStatus();
|
||||
|
||||
// Manual configuration
|
||||
void begin(uint8_t *mac, IPAddress ip);
|
||||
void begin(uint8_t *mac, IPAddress ip, IPAddress dns);
|
||||
void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway);
|
||||
void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
|
||||
void init(uint8_t sspin = 10);
|
||||
|
||||
void MACAddress(uint8_t *mac_address);
|
||||
IPAddress localIP();
|
||||
IPAddress subnetMask();
|
||||
IPAddress gatewayIP();
|
||||
IPAddress dnsServerIP() { return _dnsServerAddress; }
|
||||
|
||||
void setMACAddress(const uint8_t *mac_address);
|
||||
void setLocalIP(const IPAddress local_ip);
|
||||
void setSubnetMask(const IPAddress subnet);
|
||||
void setGatewayIP(const IPAddress gateway);
|
||||
void setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; }
|
||||
void setRetransmissionTimeout(uint16_t milliseconds);
|
||||
void setRetransmissionCount(uint8_t num);
|
||||
|
||||
friend class EthernetClient;
|
||||
friend class EthernetServer;
|
||||
friend class EthernetUDP;
|
||||
private:
|
||||
// Opens a socket(TCP or UDP or IP_RAW mode)
|
||||
uint8_t socketBegin(uint8_t protocol, uint16_t port);
|
||||
uint8_t socketBeginMulticast(uint8_t protocol, IPAddress ip,uint16_t port);
|
||||
uint8_t socketStatus(uint8_t s);
|
||||
// Close socket
|
||||
void socketClose(uint8_t s);
|
||||
// Establish TCP connection (Active connection)
|
||||
void socketConnect(uint8_t s, uint8_t * addr, uint16_t port);
|
||||
// disconnect the connection
|
||||
void socketDisconnect(uint8_t s);
|
||||
// Establish TCP connection (Passive connection)
|
||||
uint8_t socketListen(uint8_t s);
|
||||
// Send data (TCP)
|
||||
uint16_t socketSend(uint8_t s, const uint8_t * buf, uint16_t len);
|
||||
uint16_t socketSendAvailable(uint8_t s);
|
||||
// Receive data (TCP)
|
||||
int socketRecv(uint8_t s, uint8_t * buf, int16_t len);
|
||||
uint16_t socketRecvAvailable(uint8_t s);
|
||||
uint8_t socketPeek(uint8_t s);
|
||||
// sets up a UDP datagram, the data for which will be provided by one
|
||||
// or more calls to bufferData and then finally sent with sendUDP.
|
||||
// return true if the datagram was successfully set up, or false if there was an error
|
||||
bool socketStartUDP(uint8_t s, uint8_t* addr, uint16_t port);
|
||||
// copy up to len bytes of data from buf into a UDP datagram to be
|
||||
// sent later by sendUDP. Allows datagrams to be built up from a series of bufferData calls.
|
||||
// return Number of bytes successfully buffered
|
||||
uint16_t socketBufferData(uint8_t s, uint16_t offset, const uint8_t* buf, uint16_t len);
|
||||
// Send a UDP datagram built up from a sequence of startUDP followed by one or more
|
||||
// calls to bufferData.
|
||||
// return true if the datagram was successfully sent, or false if there was an error
|
||||
bool socketSendUDP(uint8_t s);
|
||||
// Initialize the "random" source port number
|
||||
void socketPortRand(uint16_t n);
|
||||
};
|
||||
|
||||
extern EthernetClass Ethernet;
|
||||
|
||||
|
||||
#define UDP_TX_PACKET_MAX_SIZE 24
|
||||
|
||||
class EthernetUDP : public UDP {
|
||||
private:
|
||||
uint16_t _port; // local port to listen on
|
||||
IPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed
|
||||
uint16_t _remotePort; // remote port for the incoming packet whilst it's being processed
|
||||
uint16_t _offset; // offset into the packet being sent
|
||||
|
||||
protected:
|
||||
uint8_t sockindex;
|
||||
uint16_t _remaining; // remaining bytes of incoming packet yet to be processed
|
||||
|
||||
public:
|
||||
EthernetUDP() : sockindex(MAX_SOCK_NUM) {} // Constructor
|
||||
virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
|
||||
virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
|
||||
virtual void stop(); // Finish with the UDP socket
|
||||
|
||||
// Sending UDP packets
|
||||
|
||||
// Start building up a packet to send to the remote host specific in ip and port
|
||||
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
|
||||
virtual int beginPacket(IPAddress ip, uint16_t port);
|
||||
// Start building up a packet to send to the remote host specific in host and port
|
||||
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
|
||||
virtual int beginPacket(const char *host, uint16_t port);
|
||||
// Finish off this packet and send it
|
||||
// Returns 1 if the packet was sent successfully, 0 if there was an error
|
||||
virtual int endPacket();
|
||||
// Write a single byte into the packet
|
||||
virtual size_t write(uint8_t);
|
||||
// Write size bytes from buffer into the packet
|
||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||
|
||||
using Print::write;
|
||||
|
||||
// Start processing the next available incoming packet
|
||||
// Returns the size of the packet in bytes, or 0 if no packets are available
|
||||
virtual int parsePacket();
|
||||
// Number of bytes remaining in the current packet
|
||||
virtual int available();
|
||||
// Read a single byte from the current packet
|
||||
virtual int read();
|
||||
// Read up to len bytes from the current packet and place them into buffer
|
||||
// Returns the number of bytes read, or 0 if none are available
|
||||
virtual int read(unsigned char* buffer, size_t len);
|
||||
// Read up to len characters from the current packet and place them into buffer
|
||||
// Returns the number of characters read, or 0 if none are available
|
||||
virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
|
||||
// Return the next byte from the current packet without moving on to the next byte
|
||||
virtual int peek();
|
||||
virtual void flush(); // Finish reading the current packet
|
||||
|
||||
// Return the IP address of the host who sent the current incoming packet
|
||||
virtual IPAddress remoteIP() { return _remoteIP; };
|
||||
// Return the port of the host who sent the current incoming packet
|
||||
virtual uint16_t remotePort() { return _remotePort; };
|
||||
virtual uint16_t localPort() { return _port; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class EthernetClient : public Client {
|
||||
public:
|
||||
EthernetClient() : sockindex(MAX_SOCK_NUM), _timeout(1000) { }
|
||||
EthernetClient(uint8_t s) : sockindex(s), _timeout(1000) { }
|
||||
|
||||
uint8_t status();
|
||||
virtual int connect(IPAddress ip, uint16_t port);
|
||||
virtual int connect(const char *host, uint16_t port);
|
||||
virtual int availableForWrite(void);
|
||||
virtual size_t write(uint8_t);
|
||||
virtual size_t write(const uint8_t *buf, size_t size);
|
||||
virtual int available();
|
||||
virtual int read();
|
||||
virtual int read(uint8_t *buf, size_t size);
|
||||
virtual int peek();
|
||||
virtual void flush();
|
||||
virtual void stop();
|
||||
virtual uint8_t connected();
|
||||
virtual operator bool() { return sockindex < MAX_SOCK_NUM; }
|
||||
virtual bool operator==(const bool value) { return bool() == value; }
|
||||
virtual bool operator!=(const bool value) { return bool() != value; }
|
||||
virtual bool operator==(const EthernetClient&);
|
||||
virtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); }
|
||||
uint8_t getSocketNumber() const { return sockindex; }
|
||||
virtual uint16_t localPort();
|
||||
virtual IPAddress remoteIP();
|
||||
virtual uint16_t remotePort();
|
||||
virtual void setConnectionTimeout(uint16_t timeout) { _timeout = timeout; }
|
||||
|
||||
friend class EthernetServer;
|
||||
|
||||
using Print::write;
|
||||
|
||||
private:
|
||||
uint8_t sockindex; // MAX_SOCK_NUM means client not in use
|
||||
uint16_t _timeout;
|
||||
};
|
||||
|
||||
|
||||
class EthernetServer : public Server {
|
||||
private:
|
||||
uint16_t _port;
|
||||
public:
|
||||
EthernetServer(uint16_t port) : _port(port) { }
|
||||
EthernetClient available();
|
||||
EthernetClient accept();
|
||||
virtual void begin();
|
||||
virtual size_t write(uint8_t);
|
||||
virtual size_t write(const uint8_t *buf, size_t size);
|
||||
virtual operator bool();
|
||||
using Print::write;
|
||||
//void statusreport();
|
||||
|
||||
// TODO: make private when socket allocation moves to EthernetClass
|
||||
static uint16_t server_port[MAX_SOCK_NUM];
|
||||
};
|
||||
|
||||
|
||||
class DhcpClass {
|
||||
private:
|
||||
uint32_t _dhcpInitialTransactionId;
|
||||
uint32_t _dhcpTransactionId;
|
||||
uint8_t _dhcpMacAddr[6];
|
||||
#ifdef __arm__
|
||||
uint8_t _dhcpLocalIp[4] __attribute__((aligned(4)));
|
||||
uint8_t _dhcpSubnetMask[4] __attribute__((aligned(4)));
|
||||
uint8_t _dhcpGatewayIp[4] __attribute__((aligned(4)));
|
||||
uint8_t _dhcpDhcpServerIp[4] __attribute__((aligned(4)));
|
||||
uint8_t _dhcpDnsServerIp[4] __attribute__((aligned(4)));
|
||||
#else
|
||||
uint8_t _dhcpLocalIp[4];
|
||||
uint8_t _dhcpSubnetMask[4];
|
||||
uint8_t _dhcpGatewayIp[4];
|
||||
uint8_t _dhcpDhcpServerIp[4];
|
||||
uint8_t _dhcpDnsServerIp[4];
|
||||
#endif
|
||||
uint32_t _dhcpLeaseTime;
|
||||
uint32_t _dhcpT1, _dhcpT2;
|
||||
uint32_t _renewInSec;
|
||||
uint32_t _rebindInSec;
|
||||
unsigned long _timeout;
|
||||
unsigned long _responseTimeout;
|
||||
unsigned long _lastCheckLeaseMillis;
|
||||
uint8_t _dhcp_state;
|
||||
EthernetUDP _dhcpUdpSocket;
|
||||
|
||||
int request_DHCP_lease();
|
||||
void reset_DHCP_lease();
|
||||
void presend_DHCP();
|
||||
void send_DHCP_MESSAGE(uint8_t, uint16_t);
|
||||
void printByte(char *, uint8_t);
|
||||
|
||||
uint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId);
|
||||
public:
|
||||
IPAddress getLocalIp();
|
||||
IPAddress getSubnetMask();
|
||||
IPAddress getGatewayIp();
|
||||
IPAddress getDhcpServerIp();
|
||||
IPAddress getDnsServerIp();
|
||||
|
||||
int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);
|
||||
int checkLease();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,240 @@
|
||||
/****************************************************************************************************************************
|
||||
EthernetServer.cpp
|
||||
|
||||
EthernetWebServer is a library for the Ethernet shields to run WebServer
|
||||
|
||||
Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer
|
||||
Licensed under MIT license
|
||||
Version: 1.0.9
|
||||
|
||||
Copyright 2018 Paul Stoffregen
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries
|
||||
1.0.1 K Hoang 20/02/2020 Add support to lambda functions
|
||||
1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60
|
||||
1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards
|
||||
1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards
|
||||
1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense,
|
||||
Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc.
|
||||
More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge
|
||||
1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards
|
||||
1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards
|
||||
1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards.
|
||||
1.0.9 K Hoang 15/05/2020 Add EthernetWrapper.h for easier W5x00 support as well as more Ethernet libs in the future.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "EthernetLarge.h"
|
||||
#include "utility/w5100.h"
|
||||
|
||||
uint16_t EthernetServer::server_port[MAX_SOCK_NUM];
|
||||
|
||||
|
||||
void EthernetServer::begin()
|
||||
{
|
||||
uint8_t sockindex = Ethernet.socketBegin(SnMR::TCP, _port);
|
||||
if (sockindex < MAX_SOCK_NUM) {
|
||||
if (Ethernet.socketListen(sockindex)) {
|
||||
server_port[sockindex] = _port;
|
||||
} else {
|
||||
Ethernet.socketDisconnect(sockindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EthernetClient EthernetServer::available()
|
||||
{
|
||||
bool listening = false;
|
||||
uint8_t sockindex = MAX_SOCK_NUM;
|
||||
uint8_t chip, maxindex=MAX_SOCK_NUM;
|
||||
|
||||
chip = W5100.getChip();
|
||||
if (!chip) return EthernetClient(MAX_SOCK_NUM);
|
||||
#if MAX_SOCK_NUM > 4
|
||||
if (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets
|
||||
#endif
|
||||
|
||||
for (uint8_t i=0; i < maxindex; i++)
|
||||
{
|
||||
if (server_port[i] == _port)
|
||||
{
|
||||
uint8_t stat = Ethernet.socketStatus(i);
|
||||
if (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT)
|
||||
{
|
||||
if (Ethernet.socketRecvAvailable(i) > 0)
|
||||
{
|
||||
sockindex = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
// remote host closed connection, our end still open
|
||||
if (stat == SnSR::CLOSE_WAIT)
|
||||
{
|
||||
Ethernet.socketDisconnect(i);
|
||||
// status becomes LAST_ACK for short time
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (stat == SnSR::LISTEN)
|
||||
{
|
||||
listening = true;
|
||||
}
|
||||
else if (stat == SnSR::CLOSED)
|
||||
{
|
||||
server_port[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!listening)
|
||||
{
|
||||
begin();
|
||||
}
|
||||
|
||||
return EthernetClient(sockindex);
|
||||
}
|
||||
|
||||
EthernetClient EthernetServer::accept()
|
||||
{
|
||||
bool listening = false;
|
||||
uint8_t sockindex = MAX_SOCK_NUM;
|
||||
uint8_t chip, maxindex=MAX_SOCK_NUM;
|
||||
|
||||
chip = W5100.getChip();
|
||||
if (!chip) return EthernetClient(MAX_SOCK_NUM);
|
||||
#if MAX_SOCK_NUM > 4
|
||||
if (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets
|
||||
#endif
|
||||
|
||||
for (uint8_t i=0; i < maxindex; i++)
|
||||
{
|
||||
if (server_port[i] == _port)
|
||||
{
|
||||
uint8_t stat = Ethernet.socketStatus(i);
|
||||
|
||||
if (sockindex == MAX_SOCK_NUM && (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT))
|
||||
{
|
||||
// Return the connected client even if no data received.
|
||||
// Some protocols like FTP expect the server to send the
|
||||
// first data.
|
||||
sockindex = i;
|
||||
server_port[i] = 0; // only return the client once
|
||||
}
|
||||
else if (stat == SnSR::LISTEN)
|
||||
{
|
||||
listening = true;
|
||||
}
|
||||
else if (stat == SnSR::CLOSED)
|
||||
{
|
||||
server_port[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!listening)
|
||||
begin();
|
||||
|
||||
return EthernetClient(sockindex);
|
||||
}
|
||||
|
||||
EthernetServer::operator bool()
|
||||
{
|
||||
uint8_t maxindex=MAX_SOCK_NUM;
|
||||
#if MAX_SOCK_NUM > 4
|
||||
if (W5100.getChip() == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets
|
||||
#endif
|
||||
|
||||
for (uint8_t i=0; i < maxindex; i++)
|
||||
{
|
||||
if (server_port[i] == _port)
|
||||
{
|
||||
if (Ethernet.socketStatus(i) == SnSR::LISTEN)
|
||||
{
|
||||
return true; // server is listening for incoming clients
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void EthernetServer::statusreport()
|
||||
{
|
||||
Serial.printf("EthernetServer, port=%d\n", _port);
|
||||
for (uint8_t i=0; i < MAX_SOCK_NUM; i++) {
|
||||
uint16_t port = server_port[i];
|
||||
uint8_t stat = Ethernet.socketStatus(i);
|
||||
const char *name;
|
||||
switch (stat) {
|
||||
case 0x00: name = "CLOSED"; break;
|
||||
case 0x13: name = "INIT"; break;
|
||||
case 0x14: name = "LISTEN"; break;
|
||||
case 0x15: name = "SYNSENT"; break;
|
||||
case 0x16: name = "SYNRECV"; break;
|
||||
case 0x17: name = "ESTABLISHED"; break;
|
||||
case 0x18: name = "FIN_WAIT"; break;
|
||||
case 0x1A: name = "CLOSING"; break;
|
||||
case 0x1B: name = "TIME_WAIT"; break;
|
||||
case 0x1C: name = "CLOSE_WAIT"; break;
|
||||
case 0x1D: name = "LAST_ACK"; break;
|
||||
case 0x22: name = "UDP"; break;
|
||||
case 0x32: name = "IPRAW"; break;
|
||||
case 0x42: name = "MACRAW"; break;
|
||||
case 0x5F: name = "PPPOE"; break;
|
||||
default: name = "???";
|
||||
}
|
||||
int avail = Ethernet.socketRecvAvailable(i);
|
||||
Serial.printf(" %d: port=%d, status=%s (0x%02X), avail=%d\n",
|
||||
i, port, name, stat, avail);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t EthernetServer::write(uint8_t b)
|
||||
{
|
||||
return write(&b, 1);
|
||||
}
|
||||
|
||||
size_t EthernetServer::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
uint8_t chip, maxindex=MAX_SOCK_NUM;
|
||||
|
||||
chip = W5100.getChip();
|
||||
if (!chip) return 0;
|
||||
#if MAX_SOCK_NUM > 4
|
||||
if (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets
|
||||
#endif
|
||||
available();
|
||||
|
||||
for (uint8_t i=0; i < maxindex; i++)
|
||||
{
|
||||
if (server_port[i] == _port)
|
||||
{
|
||||
if (Ethernet.socketStatus(i) == SnSR::ESTABLISHED)
|
||||
{
|
||||
Ethernet.socketSend(i, buffer, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
@ -0,0 +1,703 @@
|
||||
/****************************************************************************************************************************
|
||||
w5100.cpp - Driver for W5x00
|
||||
|
||||
EthernetWebServer is a library for the Ethernet shields to run WebServer
|
||||
|
||||
Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer
|
||||
Licensed under MIT license
|
||||
Version: 1.0.9
|
||||
|
||||
Copyright 2018 Paul Stoffregen
|
||||
Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
|
||||
|
||||
This file is free software; you can redistribute it and/or modify
|
||||
it under the terms of either the GNU General Public License version 2
|
||||
or the GNU Lesser General Public License version 2.1, both as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries
|
||||
1.0.1 K Hoang 20/02/2020 Add support to lambda functions
|
||||
1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60
|
||||
1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards
|
||||
1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards
|
||||
1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense,
|
||||
Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc.
|
||||
More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge
|
||||
1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards
|
||||
1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards
|
||||
1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards.
|
||||
1.0.9 K Hoang 15/05/2020 Add EthernetWrapper.h for easier W5x00 support as well as more Ethernet libs in the future.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "EthernetLarge.h"
|
||||
#include "w5100.h"
|
||||
|
||||
#define W5100_DEBUG 1
|
||||
|
||||
/***************************************************/
|
||||
/** Default SS pin setting **/
|
||||
/***************************************************/
|
||||
|
||||
// If variant.h or other headers specifically define the
|
||||
// default SS pin for ethernet, use it.
|
||||
#if defined(PIN_SPI_SS_ETHERNET_LIB)
|
||||
|
||||
#define SS_PIN_DEFAULT PIN_SPI_SS_ETHERNET_LIB
|
||||
//KH
|
||||
#warning w5100.cpp Use PIN_SPI_SS_ETHERNET_LIB defined, change SS_PIN_DEFAULT to PIN_SPI_SS_ETHERNET_LIB
|
||||
|
||||
// MKR boards default to pin 5 for MKR ETH
|
||||
// Pins 8-10 are MOSI/SCK/MISO on MRK, so don't use pin 10
|
||||
#elif defined(USE_ARDUINO_MKR_PIN_LAYOUT) || defined(ARDUINO_SAMD_MKRZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWAN1300)
|
||||
|
||||
#define SS_PIN_DEFAULT 5
|
||||
//KH
|
||||
#warning w5100.cpp Use MKR, change SS_PIN_DEFAULT to 5
|
||||
|
||||
// For boards using AVR, assume shields with SS on pin 10
|
||||
// will be used. This allows for Arduino Mega (where
|
||||
// SS is pin 53) and Arduino Leonardo (where SS is pin 17)
|
||||
// to work by default with Arduino Ethernet Shield R2 & R3.
|
||||
#elif defined(__AVR__)
|
||||
|
||||
#define SS_PIN_DEFAULT 10
|
||||
//KH
|
||||
#warning w5100.cpp Use __AVR__, change SS_PIN_DEFAULT to 10
|
||||
|
||||
// If variant.h or other headers define these names
|
||||
// use them if none of the other cases match
|
||||
#elif defined(PIN_SPI_SS)
|
||||
|
||||
#if defined(__SAMD21G18A__)
|
||||
//10 - 2 (6 conflict) all not OK for Nano 33 IoT !!! SPI corrupted???
|
||||
#warning w5100.cpp Use __SAMD21G18A__, change SS_PIN_DEFAULT to 10
|
||||
#define SS_PIN_DEFAULT 10
|
||||
#else
|
||||
#define SS_PIN_DEFAULT PIN_SPI_SS
|
||||
|
||||
//KH
|
||||
#warning w5100.cpp Use PIN_SPI_SS defined, change SS_PIN_DEFAULT to PIN_SPI_SS
|
||||
#endif
|
||||
|
||||
#elif defined(CORE_SS0_PIN)
|
||||
#define SS_PIN_DEFAULT CORE_SS0_PIN
|
||||
|
||||
//KH
|
||||
#warning w5100.cpp Use CORE_SS0_PIN defined, change SS_PIN_DEFAULT to CORE_SS0_PIN
|
||||
|
||||
//KH for ESP32
|
||||
#elif defined(ESP32)
|
||||
//pin SS already defined in ESP32 as pin 5, don't use this as conflict with SPIFFS, EEPROM, etc.
|
||||
// Use in GPIO22
|
||||
#warning w5100.cpp Use ESP32, change SS_PIN_DEFAULT to GPIO22, MOSI(23), MISO(19), SCK(18)
|
||||
#define SS_PIN_DEFAULT 22 //SS
|
||||
///////
|
||||
|
||||
//KH for ESP8266
|
||||
#elif defined(ESP8266)
|
||||
//pin SS already defined in ESP8266 as pin 15. Conflict => Move to pin GPIO4 (D2)
|
||||
#warning w5100.cpp Use ESP8266, change SS_PIN_DEFAULT to SS(4), MOSI(13), MISO(12), SCK(14)
|
||||
#define SS_PIN_DEFAULT D2 // GPIO4, SS
|
||||
|
||||
///////
|
||||
|
||||
// As a final fallback, use pin 10
|
||||
#else
|
||||
#define SS_PIN_DEFAULT 10
|
||||
|
||||
//KH
|
||||
#warning w5100.cpp Use fallback, change SS_PIN_DEFAULT to 10
|
||||
|
||||
#endif
|
||||
|
||||
// W5100 controller instance
|
||||
uint8_t W5100Class::chip = 0;
|
||||
uint8_t W5100Class::CH_BASE_MSB;
|
||||
uint8_t W5100Class::ss_pin = SS_PIN_DEFAULT;
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
uint16_t W5100Class::SSIZE = 2048;
|
||||
uint16_t W5100Class::SMASK = 0x07FF;
|
||||
#endif
|
||||
W5100Class W5100;
|
||||
|
||||
// pointers and bitmasks for optimized SS pin
|
||||
#if defined(__AVR__)
|
||||
volatile uint8_t * W5100Class::ss_pin_reg;
|
||||
uint8_t W5100Class::ss_pin_mask;
|
||||
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)
|
||||
volatile uint8_t * W5100Class::ss_pin_reg;
|
||||
#elif defined(__IMXRT1062__)
|
||||
volatile uint32_t * W5100Class::ss_pin_reg;
|
||||
uint32_t W5100Class::ss_pin_mask;
|
||||
#elif defined(__MKL26Z64__)
|
||||
volatile uint8_t * W5100Class::ss_pin_reg;
|
||||
uint8_t W5100Class::ss_pin_mask;
|
||||
#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)
|
||||
volatile uint32_t * W5100Class::ss_pin_reg;
|
||||
uint32_t W5100Class::ss_pin_mask;
|
||||
#elif defined(__PIC32MX__)
|
||||
volatile uint32_t * W5100Class::ss_pin_reg;
|
||||
uint32_t W5100Class::ss_pin_mask;
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
volatile uint32_t * W5100Class::ss_pin_reg;
|
||||
uint32_t W5100Class::ss_pin_mask;
|
||||
#elif defined(__SAMD21G18A__)
|
||||
volatile uint32_t * W5100Class::ss_pin_reg;
|
||||
uint32_t W5100Class::ss_pin_mask;
|
||||
#warning w5100.cpp Use __SAMD21G18A__
|
||||
#endif
|
||||
|
||||
// KH
|
||||
uint8_t W5100Class::init(uint8_t socketNumbers, uint8_t new_ss_pin)
|
||||
{
|
||||
// KH
|
||||
uint8_t i;
|
||||
|
||||
if (initialized) return 1;
|
||||
|
||||
// Many Ethernet shields have a CAT811 or similar reset chip
|
||||
// connected to W5100 or W5200 chips. The W5200 will not work at
|
||||
// all, and may even drive its MISO pin, until given an active low
|
||||
// reset pulse! The CAT811 has a 240 ms typical pulse length, and
|
||||
// a 400 ms worst case maximum pulse length. MAX811 has a worst
|
||||
// case maximum 560 ms pulse length. This delay is meant to wait
|
||||
// until the reset pulse is ended. If your hardware has a shorter
|
||||
// reset time, this can be edited or removed.
|
||||
delay(560);
|
||||
|
||||
//W5100Class::ss_pin = new_ss_pin;
|
||||
|
||||
#if ( W5100_DEBUG > 0 )
|
||||
//KH
|
||||
Serial.print("\nW5100 init, using SS_PIN_DEFAULT = ");
|
||||
Serial.print(SS_PIN_DEFAULT);
|
||||
Serial.print(", new ss_pin = ");
|
||||
Serial.print(new_ss_pin);
|
||||
Serial.print(", W5100Class::ss_pin = ");
|
||||
Serial.println(W5100Class::ss_pin);
|
||||
#endif
|
||||
|
||||
SPI.begin();
|
||||
|
||||
initSS();
|
||||
resetSS();
|
||||
|
||||
// From #define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0)
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
|
||||
// Attempt W5200 detection first, because W5200 does not properly
|
||||
// reset its SPI state when CS goes high (inactive). Communication
|
||||
// from detecting the other chips can leave the W5200 in a state
|
||||
// where it won't recover, unless given a reset pulse.
|
||||
if (isW5200())
|
||||
{
|
||||
CH_BASE_MSB = 0x40;
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
#if MAX_SOCK_NUM <= 1
|
||||
SSIZE = 16384;
|
||||
#elif MAX_SOCK_NUM <= 2
|
||||
SSIZE = 8192;
|
||||
#elif MAX_SOCK_NUM <= 4
|
||||
SSIZE = 4096;
|
||||
#else
|
||||
SSIZE = 2048;
|
||||
#endif
|
||||
SMASK = SSIZE - 1;
|
||||
#endif
|
||||
for (i=0; i<MAX_SOCK_NUM; i++)
|
||||
{
|
||||
writeSnRX_SIZE(i, SSIZE >> 10);
|
||||
writeSnTX_SIZE(i, SSIZE >> 10);
|
||||
}
|
||||
for (; i<8; i++)
|
||||
{
|
||||
writeSnRX_SIZE(i, 0);
|
||||
writeSnTX_SIZE(i, 0);
|
||||
}
|
||||
|
||||
#if ( W5100_DEBUG > 0 )
|
||||
Serial.print("W5100::init: W5200, SSIZE =");
|
||||
Serial.println(SSIZE);
|
||||
#endif
|
||||
|
||||
// Try W5500 next. Wiznet finally seems to have implemented
|
||||
// SPI well with this chip. It appears to be very resilient,
|
||||
// so try it after the fragile W5200
|
||||
}
|
||||
else if (isW5500())
|
||||
{
|
||||
CH_BASE_MSB = 0x10;
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
#if MAX_SOCK_NUM <= 1
|
||||
SSIZE = 16384;
|
||||
#elif MAX_SOCK_NUM <= 2
|
||||
SSIZE = 8192;
|
||||
#elif MAX_SOCK_NUM <= 4
|
||||
SSIZE = 4096;
|
||||
#else
|
||||
SSIZE = 2048;
|
||||
#endif
|
||||
SMASK = SSIZE - 1;
|
||||
for (i=0; i<MAX_SOCK_NUM; i++)
|
||||
{
|
||||
writeSnRX_SIZE(i, SSIZE >> 10);
|
||||
writeSnTX_SIZE(i, SSIZE >> 10);
|
||||
}
|
||||
for (; i<8; i++)
|
||||
{
|
||||
writeSnRX_SIZE(i, 0);
|
||||
writeSnTX_SIZE(i, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ( W5100_DEBUG > 0 )
|
||||
Serial.print("W5100::init: W5500, SSIZE =");
|
||||
Serial.println(SSIZE);
|
||||
#endif
|
||||
|
||||
|
||||
// Try W5100 last. This simple chip uses fixed 4 byte frames
|
||||
// for every 8 bit access. Terribly inefficient, but so simple
|
||||
// it recovers from "hearing" unsuccessful W5100 or W5200
|
||||
// communication. W5100 is also the only chip without a VERSIONR
|
||||
// register for identification, so we check this last.
|
||||
} else if (isW5100())
|
||||
{
|
||||
CH_BASE_MSB = 0x04;
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
#if MAX_SOCK_NUM <= 1
|
||||
SSIZE = 8192;
|
||||
writeTMSR(0x03);
|
||||
writeRMSR(0x03);
|
||||
#elif MAX_SOCK_NUM <= 2
|
||||
SSIZE = 4096;
|
||||
writeTMSR(0x0A);
|
||||
writeRMSR(0x0A);
|
||||
#else
|
||||
SSIZE = 2048;
|
||||
writeTMSR(0x55);
|
||||
writeRMSR(0x55);
|
||||
#endif
|
||||
SMASK = SSIZE - 1;
|
||||
#else
|
||||
writeTMSR(0x55);
|
||||
writeRMSR(0x55);
|
||||
#endif
|
||||
|
||||
#if ( W5100_DEBUG > 0 )
|
||||
Serial.print("W5100::init: W5100, SSIZE =");
|
||||
Serial.println(SSIZE);
|
||||
#endif
|
||||
|
||||
// No hardware seems to be present. Or it could be a W5200
|
||||
// that's heard other SPI communication if its chip select
|
||||
// pin wasn't high when a SD card or other SPI chip was used.
|
||||
}
|
||||
else
|
||||
{
|
||||
#if ( W5100_DEBUG > 0 )
|
||||
Serial.println("no chip :-(");
|
||||
#endif
|
||||
|
||||
chip = 0;
|
||||
SPI.endTransaction();
|
||||
return 0; // no known chip is responding :-(
|
||||
}
|
||||
SPI.endTransaction();
|
||||
initialized = true;
|
||||
return 1; // successful init
|
||||
}
|
||||
|
||||
// Soft reset the Wiznet chip, by writing to its MR register reset bit
|
||||
uint8_t W5100Class::softReset(void)
|
||||
{
|
||||
uint16_t count=0;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("EthernetLarge:Wiznet soft reset");
|
||||
#endif
|
||||
|
||||
// write to reset bit
|
||||
writeMR(0x80);
|
||||
// then wait for soft reset to complete
|
||||
do
|
||||
{
|
||||
uint8_t mr = readMR();
|
||||
|
||||
#if ( W5100_DEBUG > 2 )
|
||||
Serial.print("mr=");
|
||||
Serial.println(mr, HEX);
|
||||
#endif
|
||||
|
||||
if (mr == 0)
|
||||
return 1;
|
||||
|
||||
delay(1);
|
||||
} while (++count < 20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t W5100Class::isW5100(void)
|
||||
{
|
||||
chip = 51;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("W5100.cpp: detect W5100 chip");
|
||||
#endif
|
||||
|
||||
if (!softReset())
|
||||
return 0;
|
||||
|
||||
writeMR(0x10);
|
||||
if (readMR() != 0x10)
|
||||
return 0;
|
||||
|
||||
writeMR(0x12);
|
||||
if (readMR() != 0x12)
|
||||
return 0;
|
||||
|
||||
writeMR(0x00);
|
||||
if (readMR() != 0x00)
|
||||
return 0;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("chip is W5100");
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t W5100Class::isW5200(void)
|
||||
{
|
||||
chip = 52;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("W5100.cpp: detect W5200 chip");
|
||||
#endif
|
||||
|
||||
if (!softReset())
|
||||
return 0;
|
||||
|
||||
writeMR(0x08);
|
||||
if (readMR() != 0x08)
|
||||
return 0;
|
||||
|
||||
writeMR(0x10);
|
||||
if (readMR() != 0x10)
|
||||
return 0;
|
||||
|
||||
writeMR(0x00);
|
||||
if (readMR() != 0x00)
|
||||
return 0;
|
||||
|
||||
int ver = readVERSIONR_W5200();
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.print("version=");
|
||||
Serial.println(ver);
|
||||
#endif
|
||||
|
||||
if (ver != 3)
|
||||
return 0;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("chip is W5200");
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t W5100Class::isW5500(void)
|
||||
{
|
||||
chip = 55;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("W5100.cpp: detect W5500 chip");
|
||||
#endif
|
||||
|
||||
if (!softReset())
|
||||
return 0;
|
||||
|
||||
writeMR(0x08);
|
||||
if (readMR() != 0x08)
|
||||
return 0;
|
||||
|
||||
writeMR(0x10);
|
||||
if (readMR() != 0x10)
|
||||
return 0;
|
||||
|
||||
writeMR(0x00);
|
||||
if (readMR() != 0x00)
|
||||
return 0;
|
||||
|
||||
int ver = readVERSIONR_W5500();
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.print("version=");
|
||||
Serial.println(ver);
|
||||
#endif
|
||||
|
||||
if (ver != 4)
|
||||
return 0;
|
||||
|
||||
#if ( W5100_DEBUG > 1 )
|
||||
Serial.println("chip is W5500");
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
W5100Linkstatus W5100Class::getLinkStatus()
|
||||
{
|
||||
uint8_t phystatus;
|
||||
|
||||
// KH
|
||||
if (!initialized) return UNKNOWN;
|
||||
|
||||
switch (chip)
|
||||
{
|
||||
case 52:
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
phystatus = readPSTATUS_W5200();
|
||||
SPI.endTransaction();
|
||||
if (phystatus & 0x20)
|
||||
return LINK_ON;
|
||||
|
||||
return LINK_OFF;
|
||||
|
||||
case 55:
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
phystatus = readPHYCFGR_W5500();
|
||||
SPI.endTransaction();
|
||||
if (phystatus & 0x01)
|
||||
return LINK_ON;
|
||||
|
||||
return LINK_OFF;
|
||||
|
||||
default:
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t W5100Class::write(uint16_t addr, const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint8_t cmd[8];
|
||||
|
||||
if (chip == 51)
|
||||
{
|
||||
for (uint16_t i=0; i<len; i++)
|
||||
{
|
||||
setSS();
|
||||
SPI.transfer(0xF0);
|
||||
SPI.transfer(addr >> 8);
|
||||
SPI.transfer(addr & 0xFF);
|
||||
addr++;
|
||||
SPI.transfer(buf[i]);
|
||||
resetSS();
|
||||
}
|
||||
}
|
||||
else if (chip == 52)
|
||||
{
|
||||
setSS();
|
||||
cmd[0] = addr >> 8;
|
||||
cmd[1] = addr & 0xFF;
|
||||
cmd[2] = ((len >> 8) & 0x7F) | 0x80;
|
||||
cmd[3] = len & 0xFF;
|
||||
SPI.transfer(cmd, 4);
|
||||
|
||||
#ifdef SPI_HAS_TRANSFER_BUF
|
||||
SPI.transfer(buf, NULL, len);
|
||||
#else
|
||||
// TODO: copy 8 bytes at a time to cmd[] and block transfer
|
||||
for (uint16_t i=0; i < len; i++)
|
||||
{
|
||||
SPI.transfer(buf[i]);
|
||||
}
|
||||
#endif
|
||||
resetSS();
|
||||
}
|
||||
else
|
||||
{
|
||||
// chip == 55
|
||||
setSS();
|
||||
if (addr < 0x100)
|
||||
{
|
||||
// common registers 00nn
|
||||
cmd[0] = 0;
|
||||
cmd[1] = addr & 0xFF;
|
||||
cmd[2] = 0x04;
|
||||
}
|
||||
else if (addr < 0x8000)
|
||||
{
|
||||
// socket registers 10nn, 11nn, 12nn, 13nn, etc
|
||||
cmd[0] = 0;
|
||||
cmd[1] = addr & 0xFF;
|
||||
cmd[2] = ((addr >> 3) & 0xE0) | 0x0C;
|
||||
}
|
||||
else if (addr < 0xC000)
|
||||
{
|
||||
// transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc
|
||||
// 10## #nnn nnnn nnnn
|
||||
cmd[0] = addr >> 8;
|
||||
cmd[1] = addr & 0xFF;
|
||||
#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1
|
||||
cmd[2] = 0x14; // 16K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2
|
||||
cmd[2] = ((addr >> 8) & 0x20) | 0x14; // 8K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4
|
||||
cmd[2] = ((addr >> 7) & 0x60) | 0x14; // 4K buffers
|
||||
#else
|
||||
cmd[2] = ((addr >> 6) & 0xE0) | 0x14; // 2K buffers
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// receive buffers
|
||||
cmd[0] = addr >> 8;
|
||||
cmd[1] = addr & 0xFF;
|
||||
#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1
|
||||
cmd[2] = 0x1C; // 16K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2
|
||||
cmd[2] = ((addr >> 8) & 0x20) | 0x1C; // 8K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4
|
||||
cmd[2] = ((addr >> 7) & 0x60) | 0x1C; // 4K buffers
|
||||
#else
|
||||
cmd[2] = ((addr >> 6) & 0xE0) | 0x1C; // 2K buffers
|
||||
#endif
|
||||
}
|
||||
|
||||
if (len <= 5)
|
||||
{
|
||||
for (uint8_t i=0; i < len; i++)
|
||||
{
|
||||
cmd[i + 3] = buf[i];
|
||||
}
|
||||
|
||||
SPI.transfer(cmd, len + 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
SPI.transfer(cmd, 3);
|
||||
#ifdef SPI_HAS_TRANSFER_BUF
|
||||
SPI.transfer(buf, NULL, len);
|
||||
#else
|
||||
// TODO: copy 8 bytes at a time to cmd[] and block transfer
|
||||
for (uint16_t i=0; i < len; i++)
|
||||
{
|
||||
SPI.transfer(buf[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
resetSS();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
uint16_t W5100Class::read(uint16_t addr, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint8_t cmd[4];
|
||||
|
||||
if (chip == 51)
|
||||
{
|
||||
for (uint16_t i=0; i < len; i++)
|
||||
{
|
||||
setSS();
|
||||
#if 1
|
||||
SPI.transfer(0x0F);
|
||||
SPI.transfer(addr >> 8);
|
||||
SPI.transfer(addr & 0xFF);
|
||||
addr++;
|
||||
buf[i] = SPI.transfer(0);
|
||||
#else
|
||||
cmd[0] = 0x0F;
|
||||
cmd[1] = addr >> 8;
|
||||
cmd[2] = addr & 0xFF;
|
||||
cmd[3] = 0;
|
||||
SPI.transfer(cmd, 4); // TODO: why doesn't this work?
|
||||
buf[i] = cmd[3];
|
||||
addr++;
|
||||
#endif
|
||||
resetSS();
|
||||
}
|
||||
}
|
||||
else if (chip == 52)
|
||||
{
|
||||
setSS();
|
||||
cmd[0] = addr >> 8;
|
||||
cmd[1] = addr & 0xFF;
|
||||
cmd[2] = (len >> 8) & 0x7F;
|
||||
cmd[3] = len & 0xFF;
|
||||
SPI.transfer(cmd, 4);
|
||||
memset(buf, 0, len);
|
||||
SPI.transfer(buf, len);
|
||||
resetSS();
|
||||
}
|
||||
else
|
||||
{
|
||||
// chip == 55
|
||||
setSS();
|
||||
|
||||
if (addr < 0x100)
|
||||
{
|
||||
// common registers 00nn
|
||||
cmd[0] = 0;
|
||||
cmd[1] = addr & 0xFF;
|
||||
cmd[2] = 0x00;
|
||||
}
|
||||
else if (addr < 0x8000)
|
||||
{
|
||||
// socket registers 10nn, 11nn, 12nn, 13nn, etc
|
||||
cmd[0] = 0;
|
||||
cmd[1] = addr & 0xFF;
|
||||
cmd[2] = ((addr >> 3) & 0xE0) | 0x08;
|
||||
}
|
||||
else if (addr < 0xC000)
|
||||
{
|
||||
// transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc
|
||||
// 10## #nnn nnnn nnnn
|
||||
cmd[0] = addr >> 8;
|
||||
cmd[1] = addr & 0xFF;
|
||||
#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1
|
||||
cmd[2] = 0x10; // 16K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2
|
||||
cmd[2] = ((addr >> 8) & 0x20) | 0x10; // 8K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4
|
||||
cmd[2] = ((addr >> 7) & 0x60) | 0x10; // 4K buffers
|
||||
#else
|
||||
cmd[2] = ((addr >> 6) & 0xE0) | 0x10; // 2K buffers
|
||||
#endif
|
||||
} else
|
||||
{
|
||||
// receive buffers
|
||||
cmd[0] = addr >> 8;
|
||||
cmd[1] = addr & 0xFF;
|
||||
#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1
|
||||
cmd[2] = 0x18; // 16K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2
|
||||
cmd[2] = ((addr >> 8) & 0x20) | 0x18; // 8K buffers
|
||||
#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4
|
||||
cmd[2] = ((addr >> 7) & 0x60) | 0x18; // 4K buffers
|
||||
#else
|
||||
cmd[2] = ((addr >> 6) & 0xE0) | 0x18; // 2K buffers
|
||||
#endif
|
||||
}
|
||||
SPI.transfer(cmd, 3);
|
||||
memset(buf, 0, len);
|
||||
SPI.transfer(buf, len);
|
||||
resetSS();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd)
|
||||
{
|
||||
// Send command to socket
|
||||
writeSnCR(s, _cmd);
|
||||
// Wait for command to complete
|
||||
while (readSnCR(s)) ;
|
||||
}
|
@ -0,0 +1,632 @@
|
||||
/****************************************************************************************************************************
|
||||
w5100.cpp - Driver for W5x00
|
||||
|
||||
EthernetWebServer is a library for the Ethernet shields to run WebServer
|
||||
|
||||
Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer
|
||||
Licensed under MIT license
|
||||
Version: 1.0.9
|
||||
|
||||
Copyright 2018 Paul Stoffregen
|
||||
Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
|
||||
|
||||
This file is free software; you can redistribute it and/or modify
|
||||
it under the terms of either the GNU General Public License version 2
|
||||
or the GNU Lesser General Public License version 2.1, both as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries
|
||||
1.0.1 K Hoang 20/02/2020 Add support to lambda functions
|
||||
1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60
|
||||
1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards
|
||||
1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards
|
||||
1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense,
|
||||
Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc.
|
||||
More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge
|
||||
1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards
|
||||
1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards
|
||||
1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards.
|
||||
1.0.9 K Hoang 15/05/2020 Add EthernetWrapper.h for easier W5x00 support as well as more Ethernet libs in the future.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
// w5100.h contains private W5x00 hardware "driver" level definitions
|
||||
// which are not meant to be exposed to other libraries or Arduino users
|
||||
|
||||
#ifndef W5100_H_INCLUDED
|
||||
#define W5100_H_INCLUDED
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#ifndef USE_W5100
|
||||
#define USE_W5100 false
|
||||
#else
|
||||
#define USE_W5100 true
|
||||
#endif
|
||||
|
||||
#if !USE_W5100
|
||||
|
||||
// Safe for W5200 and W5500, but also tested OK on W5100
|
||||
// Use 14MHz if you know your W5100 can't run
|
||||
// Higher SPI clock results in faster transfer to hosts on a LAN
|
||||
// or with very low packet latency. With ordinary internet latency,
|
||||
// the TCP window size & packet loss determine your overall speed.
|
||||
#warning Use 25MHz clock for W5200/W5500. Not for W5100
|
||||
#define SPI_ETHERNET_SETTINGS SPISettings(25000000, MSBFIRST, SPI_MODE0)
|
||||
|
||||
#else
|
||||
|
||||
// Safe for all chips but too slow
|
||||
#define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0)
|
||||
#warning Use 14MHz clock for W5100/W5200/W5500. Slow.
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Require Ethernet.h, because we need MAX_SOCK_NUM
|
||||
#ifndef ethernet_h_
|
||||
#error "EthernetLarge.h must be included before w5100.h"
|
||||
#endif
|
||||
|
||||
|
||||
// Arduino 101's SPI can not run faster than 8 MHz.
|
||||
#if defined(ARDUINO_ARCH_ARC32)
|
||||
#undef SPI_ETHERNET_SETTINGS
|
||||
#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE0)
|
||||
#endif
|
||||
|
||||
// Arduino Zero can't use W5100-based shields faster than 8 MHz
|
||||
// https://github.com/arduino-libraries/Ethernet/issues/37#issuecomment-408036848
|
||||
// W5500 does seem to work at 12 MHz. Delete this if only using W5500
|
||||
#if defined(__SAMD21G18A__)
|
||||
#undef SPI_ETHERNET_SETTINGS
|
||||
//#warning Use SAMD21 architecture SPISettings(8000000, MSBFIRST, SPI_MODE3) => IP OK
|
||||
#warning Use SAMD21 architecture SPISettings(30000000, MSBFIRST, SPI_MODE3) => IP OK
|
||||
// Still not working !!! Original SPI_MODE0 not OK at all
|
||||
//#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE3)
|
||||
#define SPI_ETHERNET_SETTINGS SPISettings(30000000, MSBFIRST, SPI_MODE3)
|
||||
#endif
|
||||
|
||||
|
||||
typedef uint8_t SOCKET;
|
||||
|
||||
class SnMR {
|
||||
public:
|
||||
static const uint8_t CLOSE = 0x00;
|
||||
static const uint8_t TCP = 0x21;
|
||||
static const uint8_t UDP = 0x02;
|
||||
static const uint8_t IPRAW = 0x03;
|
||||
static const uint8_t MACRAW = 0x04;
|
||||
static const uint8_t PPPOE = 0x05;
|
||||
static const uint8_t ND = 0x20;
|
||||
static const uint8_t MULTI = 0x80;
|
||||
};
|
||||
|
||||
enum SockCMD {
|
||||
Sock_OPEN = 0x01,
|
||||
Sock_LISTEN = 0x02,
|
||||
Sock_CONNECT = 0x04,
|
||||
Sock_DISCON = 0x08,
|
||||
Sock_CLOSE = 0x10,
|
||||
Sock_SEND = 0x20,
|
||||
Sock_SEND_MAC = 0x21,
|
||||
Sock_SEND_KEEP = 0x22,
|
||||
Sock_RECV = 0x40
|
||||
};
|
||||
|
||||
class SnIR {
|
||||
public:
|
||||
static const uint8_t SEND_OK = 0x10;
|
||||
static const uint8_t TIMEOUT = 0x08;
|
||||
static const uint8_t RECV = 0x04;
|
||||
static const uint8_t DISCON = 0x02;
|
||||
static const uint8_t CON = 0x01;
|
||||
};
|
||||
|
||||
class SnSR {
|
||||
public:
|
||||
static const uint8_t CLOSED = 0x00;
|
||||
static const uint8_t INIT = 0x13;
|
||||
static const uint8_t LISTEN = 0x14;
|
||||
static const uint8_t SYNSENT = 0x15;
|
||||
static const uint8_t SYNRECV = 0x16;
|
||||
static const uint8_t ESTABLISHED = 0x17;
|
||||
static const uint8_t FIN_WAIT = 0x18;
|
||||
static const uint8_t CLOSING = 0x1A;
|
||||
static const uint8_t TIME_WAIT = 0x1B;
|
||||
static const uint8_t CLOSE_WAIT = 0x1C;
|
||||
static const uint8_t LAST_ACK = 0x1D;
|
||||
static const uint8_t UDP = 0x22;
|
||||
static const uint8_t IPRAW = 0x32;
|
||||
static const uint8_t MACRAW = 0x42;
|
||||
static const uint8_t PPPOE = 0x5F;
|
||||
};
|
||||
|
||||
class IPPROTO {
|
||||
public:
|
||||
static const uint8_t IP = 0;
|
||||
static const uint8_t ICMP = 1;
|
||||
static const uint8_t IGMP = 2;
|
||||
static const uint8_t GGP = 3;
|
||||
static const uint8_t TCP = 6;
|
||||
static const uint8_t PUP = 12;
|
||||
static const uint8_t UDP = 17;
|
||||
static const uint8_t IDP = 22;
|
||||
static const uint8_t ND = 77;
|
||||
static const uint8_t RAW = 255;
|
||||
};
|
||||
|
||||
enum W5100Linkstatus {
|
||||
UNKNOWN,
|
||||
LINK_ON,
|
||||
LINK_OFF
|
||||
};
|
||||
|
||||
class W5100Class {
|
||||
|
||||
public:
|
||||
// KH
|
||||
uint8_t init(uint8_t socketNumbers = MAX_SOCK_NUM, uint8_t new_ss_pin = 10);
|
||||
|
||||
inline void setGatewayIp(const uint8_t * addr) { writeGAR(addr); }
|
||||
inline void getGatewayIp(uint8_t * addr) { readGAR(addr); }
|
||||
|
||||
inline void setSubnetMask(const uint8_t * addr) { writeSUBR(addr); }
|
||||
inline void getSubnetMask(uint8_t * addr) { readSUBR(addr); }
|
||||
|
||||
inline void setMACAddress(const uint8_t * addr) { writeSHAR(addr); }
|
||||
inline void getMACAddress(uint8_t * addr) { readSHAR(addr); }
|
||||
|
||||
inline void setIPAddress(const uint8_t * addr) { writeSIPR(addr); }
|
||||
inline void getIPAddress(uint8_t * addr) { readSIPR(addr); }
|
||||
|
||||
inline void setRetransmissionTime(uint16_t timeout) { writeRTR(timeout); }
|
||||
inline void setRetransmissionCount(uint8_t retry) { writeRCR(retry); }
|
||||
|
||||
static void execCmdSn(SOCKET s, SockCMD _cmd);
|
||||
|
||||
|
||||
// W5100 Registers
|
||||
// ---------------
|
||||
//private:
|
||||
public:
|
||||
static uint16_t write(uint16_t addr, const uint8_t *buf, uint16_t len);
|
||||
|
||||
static uint8_t write(uint16_t addr, uint8_t data)
|
||||
{
|
||||
return write(addr, &data, 1);
|
||||
}
|
||||
|
||||
static uint16_t read(uint16_t addr, uint8_t *buf, uint16_t len);
|
||||
|
||||
static uint8_t read(uint16_t addr)
|
||||
{
|
||||
uint8_t data;
|
||||
read(addr, &data, 1);
|
||||
return data;
|
||||
}
|
||||
|
||||
#define __GP_REGISTER8(name, address) \
|
||||
static inline void write##name(uint8_t _data) { \
|
||||
write(address, _data); \
|
||||
} \
|
||||
static inline uint8_t read##name() { \
|
||||
return read(address); \
|
||||
}
|
||||
#define __GP_REGISTER16(name, address) \
|
||||
static void write##name(uint16_t _data) { \
|
||||
uint8_t buf[2]; \
|
||||
buf[0] = _data >> 8; \
|
||||
buf[1] = _data & 0xFF; \
|
||||
write(address, buf, 2); \
|
||||
} \
|
||||
static uint16_t read##name() { \
|
||||
uint8_t buf[2]; \
|
||||
read(address, buf, 2); \
|
||||
return (buf[0] << 8) | buf[1]; \
|
||||
}
|
||||
#define __GP_REGISTER_N(name, address, size) \
|
||||
static uint16_t write##name(const uint8_t *_buff) { \
|
||||
return write(address, _buff, size); \
|
||||
} \
|
||||
static uint16_t read##name(uint8_t *_buff) { \
|
||||
return read(address, _buff, size); \
|
||||
}
|
||||
|
||||
// KH
|
||||
W5100Linkstatus getLinkStatus();
|
||||
|
||||
|
||||
public:
|
||||
__GP_REGISTER8 (MR, 0x0000); // Mode
|
||||
__GP_REGISTER_N(GAR, 0x0001, 4); // Gateway IP address
|
||||
__GP_REGISTER_N(SUBR, 0x0005, 4); // Subnet mask address
|
||||
__GP_REGISTER_N(SHAR, 0x0009, 6); // Source MAC address
|
||||
__GP_REGISTER_N(SIPR, 0x000F, 4); // Source IP address
|
||||
__GP_REGISTER8 (IR, 0x0015); // Interrupt
|
||||
__GP_REGISTER8 (IMR, 0x0016); // Interrupt Mask
|
||||
__GP_REGISTER16(RTR, 0x0017); // Timeout address
|
||||
__GP_REGISTER8 (RCR, 0x0019); // Retry count
|
||||
__GP_REGISTER8 (RMSR, 0x001A); // Receive memory size (W5100 only)
|
||||
__GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size (W5100 only)
|
||||
__GP_REGISTER8 (PATR, 0x001C); // Authentication type address in PPPoE mode
|
||||
__GP_REGISTER8 (PTIMER, 0x0028); // PPP LCP Request Timer
|
||||
__GP_REGISTER8 (PMAGIC, 0x0029); // PPP LCP Magic Number
|
||||
__GP_REGISTER_N(UIPR, 0x002A, 4); // Unreachable IP address in UDP mode (W5100 only)
|
||||
__GP_REGISTER16(UPORT, 0x002E); // Unreachable Port address in UDP mode (W5100 only)
|
||||
__GP_REGISTER8 (VERSIONR_W5200,0x001F); // Chip Version Register (W5200 only)
|
||||
__GP_REGISTER8 (VERSIONR_W5500,0x0039); // Chip Version Register (W5500 only)
|
||||
__GP_REGISTER8 (PSTATUS_W5200, 0x0035); // PHY Status
|
||||
__GP_REGISTER8 (PHYCFGR_W5500, 0x002E); // PHY Configuration register, default: 10111xxx
|
||||
|
||||
|
||||
#undef __GP_REGISTER8
|
||||
#undef __GP_REGISTER16
|
||||
#undef __GP_REGISTER_N
|
||||
|
||||
// W5100 Socket registers
|
||||
// ----------------------
|
||||
private:
|
||||
static uint16_t CH_BASE(void) {
|
||||
//if (chip == 55) return 0x1000;
|
||||
//if (chip == 52) return 0x4000;
|
||||
//return 0x0400;
|
||||
return CH_BASE_MSB << 8;
|
||||
}
|
||||
static uint8_t CH_BASE_MSB; // 1 redundant byte, saves ~80 bytes code on AVR
|
||||
static const uint16_t CH_SIZE = 0x0100;
|
||||
|
||||
static inline uint8_t readSn(SOCKET s, uint16_t addr)
|
||||
{
|
||||
return read(CH_BASE() + s * CH_SIZE + addr);
|
||||
}
|
||||
static inline uint8_t writeSn(SOCKET s, uint16_t addr, uint8_t data)
|
||||
{
|
||||
return write(CH_BASE() + s * CH_SIZE + addr, data);
|
||||
}
|
||||
static inline uint16_t readSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
return read(CH_BASE() + s * CH_SIZE + addr, buf, len);
|
||||
}
|
||||
static inline uint16_t writeSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
return write(CH_BASE() + s * CH_SIZE + addr, buf, len);
|
||||
}
|
||||
|
||||
#define __SOCKET_REGISTER8(name, address) \
|
||||
static inline void write##name(SOCKET _s, uint8_t _data) { \
|
||||
writeSn(_s, address, _data); \
|
||||
} \
|
||||
static inline uint8_t read##name(SOCKET _s) { \
|
||||
return readSn(_s, address); \
|
||||
}
|
||||
#define __SOCKET_REGISTER16(name, address) \
|
||||
static void write##name(SOCKET _s, uint16_t _data) { \
|
||||
uint8_t buf[2]; \
|
||||
buf[0] = _data >> 8; \
|
||||
buf[1] = _data & 0xFF; \
|
||||
writeSn(_s, address, buf, 2); \
|
||||
} \
|
||||
static uint16_t read##name(SOCKET _s) { \
|
||||
uint8_t buf[2]; \
|
||||
readSn(_s, address, buf, 2); \
|
||||
return (buf[0] << 8) | buf[1]; \
|
||||
}
|
||||
#define __SOCKET_REGISTER_N(name, address, size) \
|
||||
static uint16_t write##name(SOCKET _s, uint8_t *_buff) { \
|
||||
return writeSn(_s, address, _buff, size); \
|
||||
} \
|
||||
static uint16_t read##name(SOCKET _s, uint8_t *_buff) { \
|
||||
return readSn(_s, address, _buff, size); \
|
||||
}
|
||||
|
||||
public:
|
||||
__SOCKET_REGISTER8(SnMR, 0x0000) // Mode
|
||||
__SOCKET_REGISTER8(SnCR, 0x0001) // Command
|
||||
__SOCKET_REGISTER8(SnIR, 0x0002) // Interrupt
|
||||
__SOCKET_REGISTER8(SnSR, 0x0003) // Status
|
||||
__SOCKET_REGISTER16(SnPORT, 0x0004) // Source Port
|
||||
__SOCKET_REGISTER_N(SnDHAR, 0x0006, 6) // Destination Hardw Addr
|
||||
__SOCKET_REGISTER_N(SnDIPR, 0x000C, 4) // Destination IP Addr
|
||||
__SOCKET_REGISTER16(SnDPORT, 0x0010) // Destination Port
|
||||
__SOCKET_REGISTER16(SnMSSR, 0x0012) // Max Segment Size
|
||||
__SOCKET_REGISTER8(SnPROTO, 0x0014) // Protocol in IP RAW Mode
|
||||
__SOCKET_REGISTER8(SnTOS, 0x0015) // IP TOS
|
||||
__SOCKET_REGISTER8(SnTTL, 0x0016) // IP TTL
|
||||
__SOCKET_REGISTER8(SnRX_SIZE, 0x001E) // RX Memory Size (W5200 only)
|
||||
__SOCKET_REGISTER8(SnTX_SIZE, 0x001F) // RX Memory Size (W5200 only)
|
||||
__SOCKET_REGISTER16(SnTX_FSR, 0x0020) // TX Free Size
|
||||
__SOCKET_REGISTER16(SnTX_RD, 0x0022) // TX Read Pointer
|
||||
__SOCKET_REGISTER16(SnTX_WR, 0x0024) // TX Write Pointer
|
||||
__SOCKET_REGISTER16(SnRX_RSR, 0x0026) // RX Free Size
|
||||
__SOCKET_REGISTER16(SnRX_RD, 0x0028) // RX Read Pointer
|
||||
__SOCKET_REGISTER16(SnRX_WR, 0x002A) // RX Write Pointer (supported?)
|
||||
|
||||
#undef __SOCKET_REGISTER8
|
||||
#undef __SOCKET_REGISTER16
|
||||
#undef __SOCKET_REGISTER_N
|
||||
|
||||
|
||||
private:
|
||||
// KH
|
||||
bool initialized = false;
|
||||
static uint8_t chip;
|
||||
static uint8_t ss_pin;
|
||||
|
||||
static uint8_t isW5100(void);
|
||||
static uint8_t isW5200(void);
|
||||
static uint8_t isW5500(void);
|
||||
|
||||
public:
|
||||
// KH
|
||||
static uint8_t softReset(void);
|
||||
static uint8_t getChip(void) { return chip; }
|
||||
#ifdef ETHERNET_LARGE_BUFFERS
|
||||
static uint16_t SSIZE;
|
||||
static uint16_t SMASK;
|
||||
#else
|
||||
static const uint16_t SSIZE = 2048;
|
||||
static const uint16_t SMASK = 0x07FF;
|
||||
#endif
|
||||
static uint16_t SBASE(uint8_t socknum)
|
||||
{
|
||||
if (chip == 51)
|
||||
{
|
||||
return socknum * SSIZE + 0x4000;
|
||||
}
|
||||
else
|
||||
{
|
||||
return socknum * SSIZE + 0x8000;
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t RBASE(uint8_t socknum)
|
||||
{
|
||||
if (chip == 51) {
|
||||
return socknum * SSIZE + 0x6000;
|
||||
}
|
||||
else
|
||||
{
|
||||
return socknum * SSIZE + 0xC000;
|
||||
}
|
||||
}
|
||||
|
||||
static bool hasOffsetAddressMapping(void)
|
||||
{
|
||||
if (chip == 55)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void setSS(uint8_t pin) { ss_pin = pin; }
|
||||
|
||||
private:
|
||||
#if defined(__AVR__)
|
||||
|
||||
#warning Use AVR architecture
|
||||
|
||||
static volatile uint8_t *ss_pin_reg;
|
||||
static uint8_t ss_pin_mask;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin));
|
||||
ss_pin_mask = digitalPinToBitMask(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg) &= ~ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg) |= ss_pin_mask;
|
||||
}
|
||||
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)
|
||||
|
||||
#warning Use MK architecture
|
||||
|
||||
static volatile uint8_t *ss_pin_reg;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = portOutputRegister(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg+256) = 1;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg+128) = 1;
|
||||
}
|
||||
#elif defined(__IMXRT1062__)
|
||||
|
||||
#warning Use Teensy architecture
|
||||
|
||||
static volatile uint32_t *ss_pin_reg;
|
||||
static uint32_t ss_pin_mask;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin));
|
||||
ss_pin_mask = digitalPinToBitMask(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg+34) = ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg+33) = ss_pin_mask;
|
||||
}
|
||||
#elif defined(__MKL26Z64__)
|
||||
static volatile uint8_t *ss_pin_reg;
|
||||
static uint8_t ss_pin_mask;
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin));
|
||||
ss_pin_mask = digitalPinToBitMask(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg+8) = ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg+4) = ss_pin_mask;
|
||||
}
|
||||
#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)
|
||||
|
||||
#warning Use SAM3 architecture
|
||||
|
||||
static volatile uint32_t *ss_pin_reg;
|
||||
static uint32_t ss_pin_mask;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = &(digitalPinToPort(ss_pin)->PIO_PER);
|
||||
ss_pin_mask = digitalPinToBitMask(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg+13) = ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg+12) = ss_pin_mask;
|
||||
}
|
||||
#elif defined(__PIC32MX__)
|
||||
static volatile uint32_t *ss_pin_reg;
|
||||
static uint32_t ss_pin_mask;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = portModeRegister(digitalPinToPort(ss_pin));
|
||||
ss_pin_mask = digitalPinToBitMask(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg+8+1) = ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg+8+2) = ss_pin_mask;
|
||||
}
|
||||
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
|
||||
#warning Use ARDUINO_ARCH_ESP8266 architecture
|
||||
|
||||
static volatile uint32_t *ss_pin_reg;
|
||||
static uint32_t ss_pin_mask;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = (volatile uint32_t*)GPO;
|
||||
ss_pin_mask = 1 << ss_pin;
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
GPOC = ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
GPOS = ss_pin_mask;
|
||||
}
|
||||
|
||||
#elif defined(__SAMD21G18A__)
|
||||
|
||||
#warning Use SAMD21 architecture
|
||||
|
||||
static volatile uint32_t *ss_pin_reg;
|
||||
static uint32_t ss_pin_mask;
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
ss_pin_reg = portModeRegister(digitalPinToPort(ss_pin));
|
||||
ss_pin_mask = digitalPinToBitMask(ss_pin);
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
*(ss_pin_reg+5) = ss_pin_mask;
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
*(ss_pin_reg+6) = ss_pin_mask;
|
||||
}
|
||||
#else
|
||||
|
||||
#warning Use Default architecture
|
||||
|
||||
inline static void initSS()
|
||||
{
|
||||
pinMode(ss_pin, OUTPUT);
|
||||
}
|
||||
|
||||
inline static void setSS()
|
||||
{
|
||||
digitalWrite(ss_pin, LOW);
|
||||
}
|
||||
|
||||
inline static void resetSS()
|
||||
{
|
||||
digitalWrite(ss_pin, HIGH);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
extern W5100Class W5100;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#ifndef htons
|
||||
#define htons(x) ( (((x)<<8)&0xFF00) | (((x)>>8)&0xFF) )
|
||||
#endif
|
||||
|
||||
#ifndef ntohs
|
||||
#define ntohs(x) htons(x)
|
||||
#endif
|
||||
|
||||
#ifndef htonl
|
||||
#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
|
||||
((x)<< 8 & 0x00FF0000UL) | \
|
||||
((x)>> 8 & 0x0000FF00UL) | \
|
||||
((x)>>24 & 0x000000FFUL) )
|
||||
#endif
|
||||
|
||||
#ifndef ntohl
|
||||
#define ntohl(x) htonl(x)
|
||||
#endif
|
||||
|
||||
#endif //W5100_H_INCLUDED
|
@ -0,0 +1,625 @@
|
||||
/*
|
||||
UIPEthernet.cpp - Arduino implementation of a uIP wrapper class.
|
||||
Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
|
||||
All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(ARDUINO)
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
#if defined(__MBED__)
|
||||
#include <mbed.h>
|
||||
#include "mbed/millis.h"
|
||||
#endif
|
||||
#include "UIPEthernet.h"
|
||||
#include "utility/logging.h"
|
||||
#include "utility/Enc28J60Network.h"
|
||||
|
||||
#include "UIPUdp.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "utility/uipopt.h"
|
||||
#include "utility/uip.h"
|
||||
#include "utility/uip_arp.h"
|
||||
}
|
||||
|
||||
#define ETH_HDR ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
|
||||
memhandle UIPEthernetClass::in_packet(NOBLOCK);
|
||||
memhandle UIPEthernetClass::uip_packet(NOBLOCK);
|
||||
uint8_t UIPEthernetClass::uip_hdrlen(0);
|
||||
uint8_t UIPEthernetClass::packetstate(0);
|
||||
|
||||
unsigned long UIPEthernetClass::periodic_timer;
|
||||
|
||||
IPAddress UIPEthernetClass::_dnsServerAddress;
|
||||
#if UIP_UDP
|
||||
DhcpClass* UIPEthernetClass::_dhcp(NULL);
|
||||
static DhcpClass s_dhcp; // Placing this instance here is saving 40K to final *.bin (see bug below)
|
||||
#endif
|
||||
|
||||
// Because uIP isn't encapsulated within a class we have to use global
|
||||
// variables, so we can only have one TCP/IP stack per program.
|
||||
|
||||
UIPEthernetClass::UIPEthernetClass()
|
||||
{
|
||||
}
|
||||
|
||||
void UIPEthernetClass::init(const uint8_t pin)
|
||||
{
|
||||
ENC28J60ControlCS = pin;
|
||||
}
|
||||
|
||||
#if UIP_UDP
|
||||
int
|
||||
UIPEthernetClass::begin(const uint8_t* mac)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var _mac_address
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::begin(const uint8_t* mac) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
//static DhcpClass s_dhcp; // <-- this is a bug !
|
||||
// I leave it there commented for history. It is bring all GCC "new" memory allocation code, making the *.bin almost 40K bigger. I've move it globally.
|
||||
_dhcp = &s_dhcp;
|
||||
// Initialise the basic info
|
||||
netInit(mac);
|
||||
|
||||
// Now try to get our config info from a DHCP server
|
||||
int ret = _dhcp->beginWithDHCP((uint8_t*)mac);
|
||||
if(ret == 1)
|
||||
{
|
||||
// We've successfully found a DHCP server and got our configuration info, so set things
|
||||
// accordingly
|
||||
configure(_dhcp->getLocalIp(),_dhcp->getDnsServerIp(),_dhcp->getGatewayIp(),_dhcp->getSubnetMask());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var _mac_address
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
IPAddress dns = ip;
|
||||
dns[3] = 1;
|
||||
begin(mac, ip, dns);
|
||||
}
|
||||
|
||||
void
|
||||
UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var _mac_address
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
IPAddress gateway = ip;
|
||||
gateway[3] = 1;
|
||||
begin(mac, ip, dns, gateway);
|
||||
}
|
||||
|
||||
void
|
||||
UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var _mac_address
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
begin(mac, ip, dns, gateway, subnet);
|
||||
}
|
||||
|
||||
void
|
||||
UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var _mac_address
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
netInit(mac);
|
||||
configure(ip,dns,gateway,subnet);
|
||||
}
|
||||
|
||||
int UIPEthernetClass::maintain(){
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::maintain() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
tick();
|
||||
int rc = DHCP_CHECK_NONE;
|
||||
#if UIP_UDP
|
||||
if(_dhcp != NULL){
|
||||
//we have a pointer to dhcp, use it
|
||||
rc = _dhcp->checkLease();
|
||||
switch ( rc ){
|
||||
case DHCP_CHECK_NONE:
|
||||
//nothing done
|
||||
break;
|
||||
case DHCP_CHECK_RENEW_OK:
|
||||
case DHCP_CHECK_REBIND_OK:
|
||||
//we might have got a new IP.
|
||||
configure(_dhcp->getLocalIp(),_dhcp->getDnsServerIp(),_dhcp->getGatewayIp(),_dhcp->getSubnetMask());
|
||||
break;
|
||||
default:
|
||||
//this is actually a error, it will retry though
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
|
||||
EthernetLinkStatus UIPEthernetClass::linkStatus()
|
||||
{
|
||||
if (!Enc28J60Network::geterevid())
|
||||
return Unknown;
|
||||
return Enc28J60Network::linkStatus() ? LinkON : LinkOFF;
|
||||
}
|
||||
|
||||
EthernetHardwareStatus UIPEthernetClass::hardwareStatus() {
|
||||
if (!Enc28J60Network::geterevid())
|
||||
return EthernetNoHardware;
|
||||
return EthernetENC28J60;
|
||||
}
|
||||
|
||||
IPAddress UIPEthernetClass::localIP()
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::localIP() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
IPAddress ret;
|
||||
uip_ipaddr_t a;
|
||||
uip_gethostaddr(a);
|
||||
return ip_addr_uip(a);
|
||||
}
|
||||
|
||||
IPAddress UIPEthernetClass::subnetMask()
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::subnetMask() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
IPAddress ret;
|
||||
uip_ipaddr_t a;
|
||||
uip_getnetmask(a);
|
||||
return ip_addr_uip(a);
|
||||
}
|
||||
|
||||
IPAddress UIPEthernetClass::gatewayIP()
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::gatewayIP() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
IPAddress ret;
|
||||
uip_ipaddr_t a;
|
||||
uip_getdraddr(a);
|
||||
return ip_addr_uip(a);
|
||||
}
|
||||
|
||||
IPAddress UIPEthernetClass::dnsServerIP()
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::dnsServerIP() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
return _dnsServerAddress;
|
||||
}
|
||||
|
||||
void
|
||||
UIPEthernetClass::tick()
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::tick() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
if (Enc28J60Network::geterevid()==0)
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_ERR
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::tick() ERROR:EREVID=0 -> Not found ENC28j60 device !! Function ended !!"));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#if defined(ESP8266)
|
||||
wdt_reset();
|
||||
#endif
|
||||
if (in_packet == NOBLOCK)
|
||||
{
|
||||
in_packet = Enc28J60Network::receivePacket();
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
if (in_packet != NOBLOCK)
|
||||
{
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::tick() DEBUG:receivePacket: "));
|
||||
LogObject.uart_send_decln(in_packet);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (in_packet != NOBLOCK)
|
||||
{
|
||||
packetstate = UIPETHERNET_FREEPACKET;
|
||||
uip_len = Enc28J60Network::blockSize(in_packet);
|
||||
if (uip_len > 0)
|
||||
{
|
||||
Enc28J60Network::readPacket(in_packet,0,(uint8_t*)uip_buf,UIP_BUFSIZE);
|
||||
if (ETH_HDR ->type == HTONS(UIP_ETHTYPE_IP))
|
||||
{
|
||||
uip_packet = in_packet; //required for upper_layer_checksum of in_packet!
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: "));
|
||||
LogObject.uart_send_decln(uip_len);
|
||||
#endif
|
||||
uip_arp_ipin();
|
||||
uip_input();
|
||||
if (uip_len > 0)
|
||||
{
|
||||
uip_arp_out();
|
||||
network_send();
|
||||
}
|
||||
}
|
||||
else if (ETH_HDR ->type == HTONS(UIP_ETHTYPE_ARP))
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::tick() DEBUG:readPacket type ARP, uip_len: "));
|
||||
LogObject.uart_send_decln(uip_len);
|
||||
#endif
|
||||
uip_arp_arpin();
|
||||
if (uip_len > 0)
|
||||
{
|
||||
network_send();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (in_packet != NOBLOCK && (packetstate & UIPETHERNET_FREEPACKET))
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::tick() DEBUG:freeing packet: "));
|
||||
LogObject.uart_send_decln(in_packet);
|
||||
#endif
|
||||
Enc28J60Network::freePacket();
|
||||
in_packet = NOBLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long now = millis();
|
||||
|
||||
#if UIP_CLIENT_TIMER >= 0
|
||||
bool periodic = (long)( now - periodic_timer ) >= 0;
|
||||
for (int i = 0; i < UIP_CONNS; i++)
|
||||
{
|
||||
#else
|
||||
if ((long)( now - periodic_timer ) >= 0)
|
||||
{
|
||||
periodic_timer = now + UIP_PERIODIC_TIMER;
|
||||
|
||||
for (int i = 0; i < UIP_CONNS; i++)
|
||||
{
|
||||
#endif
|
||||
|
||||
uip_conn = &uip_conns[i];
|
||||
|
||||
#if UIP_CLIENT_TIMER >= 0
|
||||
if (periodic)
|
||||
{
|
||||
#endif
|
||||
|
||||
uip_process(UIP_TIMER);
|
||||
|
||||
#if UIP_CLIENT_TIMER >= 0
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((uip_userdata_t*)uip_conn->appstate)!=NULL)
|
||||
{
|
||||
if ((long)( now - ((uip_userdata_t*)uip_conn->appstate)->timer) >= 0)
|
||||
{
|
||||
uip_process(UIP_POLL_REQUEST);
|
||||
((uip_userdata_t*)uip_conn->appstate)->timer = millis() + UIP_CLIENT_TIMER;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
// If the above function invocation resulted in data that
|
||||
// should be sent out on the Enc28J60Network, the global variable
|
||||
// uip_len is set to a value > 0.
|
||||
if (uip_len > 0)
|
||||
{
|
||||
uip_arp_out();
|
||||
network_send();
|
||||
}
|
||||
}
|
||||
#if UIP_CLIENT_TIMER >= 0
|
||||
if (periodic)
|
||||
{
|
||||
periodic_timer = now + UIP_PERIODIC_TIMER;
|
||||
#endif
|
||||
#if UIP_UDP
|
||||
for (int i = 0; i < UIP_UDP_CONNS; i++)
|
||||
{
|
||||
uip_udp_periodic(i);
|
||||
// If the above function invocation resulted in data that
|
||||
// should be sent out on the Enc28J60Network, the global variable
|
||||
// uip_len is set to a value > 0. */
|
||||
if (uip_len > 0)
|
||||
{
|
||||
UIPUDP::_send((uip_udp_userdata_t *)(uip_udp_conns[i].appstate));
|
||||
}
|
||||
}
|
||||
#endif /* UIP_UDP */
|
||||
}
|
||||
}
|
||||
|
||||
bool UIPEthernetClass::network_send()
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::network_send() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
if (packetstate & UIPETHERNET_SENDPACKET)
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::network_send() DEBUG:uip_packet: "));
|
||||
LogObject.uart_send_dec(uip_packet);
|
||||
LogObject.uart_send_str(F(", hdrlen: "));
|
||||
LogObject.uart_send_decln(uip_hdrlen);
|
||||
#endif
|
||||
Enc28J60Network::writePacket(uip_packet, UIP_SENDBUFFER_OFFSET,uip_buf,uip_hdrlen);
|
||||
packetstate &= ~ UIPETHERNET_SENDPACKET;
|
||||
goto sendandfree;
|
||||
}
|
||||
uip_packet = Enc28J60Network::allocBlock(uip_len + UIP_SENDBUFFER_OFFSET + UIP_SENDBUFFER_PADDING);
|
||||
if (uip_packet != NOBLOCK)
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): "));
|
||||
LogObject.uart_send_dec(uip_len);
|
||||
LogObject.uart_send_str(F(", packet: "));
|
||||
LogObject.uart_send_decln(uip_packet);
|
||||
#endif
|
||||
Enc28J60Network::writePacket(uip_packet, UIP_SENDBUFFER_OFFSET,uip_buf,uip_len);
|
||||
goto sendandfree;
|
||||
}
|
||||
return false;
|
||||
sendandfree:
|
||||
bool success = Enc28J60Network::sendPacket(uip_packet);
|
||||
Enc28J60Network::freeBlock(uip_packet);
|
||||
uip_packet = NOBLOCK;
|
||||
return success;
|
||||
}
|
||||
|
||||
void UIPEthernetClass::netInit(const uint8_t* mac) {
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::netInit(const uint8_t* mac) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
periodic_timer = millis() + UIP_PERIODIC_TIMER;
|
||||
|
||||
Enc28J60Network::init((uint8_t*)mac);
|
||||
uip_seteth_addr(mac);
|
||||
|
||||
uip_init();
|
||||
uip_arp_init();
|
||||
}
|
||||
|
||||
void UIPEthernetClass::configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) {
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
uip_ipaddr_t ipaddr;
|
||||
|
||||
uip_ip_addr(ipaddr, ip);
|
||||
uip_sethostaddr(ipaddr);
|
||||
|
||||
uip_ip_addr(ipaddr, gateway);
|
||||
uip_setdraddr(ipaddr);
|
||||
|
||||
uip_ip_addr(ipaddr, subnet);
|
||||
uip_setnetmask(ipaddr);
|
||||
|
||||
_dnsServerAddress = dns;
|
||||
}
|
||||
|
||||
UIPEthernetClass UIPEthernet;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint16_t
|
||||
UIPEthernetClass::chksum(uint16_t sum, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::chksum(uint16_t sum, const uint8_t *data, uint16_t len) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
uint16_t t;
|
||||
const uint8_t *dataptr;
|
||||
const uint8_t *last_byte;
|
||||
|
||||
dataptr = data;
|
||||
last_byte = data + len - 1;
|
||||
|
||||
while(dataptr < last_byte) { /* At least two more bytes */
|
||||
t = (dataptr[0] << 8) + dataptr[1];
|
||||
sum += t;
|
||||
if(sum < t) {
|
||||
sum++; /* carry */
|
||||
}
|
||||
dataptr += 2;
|
||||
}
|
||||
|
||||
if(dataptr == last_byte) {
|
||||
t = (dataptr[0] << 8) + 0;
|
||||
sum += t;
|
||||
if(sum < t) {
|
||||
sum++; /* carry */
|
||||
}
|
||||
}
|
||||
|
||||
/* Return sum in host byte order. */
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
uint16_t
|
||||
UIPEthernetClass::ipchksum(void)
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::ipchksum(void) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
uint16_t sum;
|
||||
|
||||
sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
|
||||
return (sum == 0) ? 0xffff : htons(sum);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint16_t
|
||||
#if UIP_UDP
|
||||
UIPEthernetClass::upper_layer_chksum(uint8_t proto)
|
||||
#else
|
||||
uip_tcpchksum(void)
|
||||
#endif
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
#if UIP_UDP
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::upper_layer_chksum(uint8_t proto) DEBUG_V3:Function started"));
|
||||
#else
|
||||
LogObject.uart_send_strln(F("uip_tcpchksum(void) INFO:Function started"));
|
||||
#endif
|
||||
#endif
|
||||
uint16_t upper_layer_len;
|
||||
uint16_t sum;
|
||||
|
||||
#if UIP_CONF_IPV6
|
||||
upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);
|
||||
#else /* UIP_CONF_IPV6 */
|
||||
upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
|
||||
#endif /* UIP_CONF_IPV6 */
|
||||
|
||||
/* First sum pseudoheader. */
|
||||
|
||||
/* IP protocol and length fields. This addition cannot carry. */
|
||||
#if UIP_UDP
|
||||
sum = upper_layer_len + proto;
|
||||
#else
|
||||
sum = upper_layer_len + UIP_PROTO_TCP;
|
||||
#endif
|
||||
/* Sum IP source and destination addresses. */
|
||||
sum = UIPEthernetClass::chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
|
||||
|
||||
uint8_t upper_layer_memlen;
|
||||
#if UIP_UDP
|
||||
switch(proto)
|
||||
{
|
||||
// case UIP_PROTO_ICMP:
|
||||
// case UIP_PROTO_ICMP6:
|
||||
// upper_layer_memlen = upper_layer_len;
|
||||
// break;
|
||||
case UIP_PROTO_UDP:
|
||||
upper_layer_memlen = UIP_UDPH_LEN;
|
||||
break;
|
||||
default:
|
||||
// case UIP_PROTO_TCP:
|
||||
#endif
|
||||
upper_layer_memlen = (BUF->tcpoffset >> 4) << 2;
|
||||
#if UIP_UDP
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
sum = UIPEthernetClass::chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_memlen);
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
#if UIP_UDP
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::upper_layer_chksum(uint8_t proto) DEBUG:uip_buf["));
|
||||
#else
|
||||
LogObject.uart_send_str(F("uip_tcpchksum(void) DEBUG:uip_buf["));
|
||||
#endif
|
||||
LogObject.uart_send_dec(UIP_IPH_LEN + UIP_LLH_LEN);
|
||||
LogObject.uart_send_str(F("-"));
|
||||
LogObject.uart_send_dec(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen);
|
||||
LogObject.uart_send_str(F("]: "));
|
||||
LogObject.uart_send_hexln(htons(sum));
|
||||
#endif
|
||||
if (upper_layer_memlen < upper_layer_len)
|
||||
{
|
||||
sum = Enc28J60Network::chksum(
|
||||
sum,
|
||||
UIPEthernetClass::uip_packet,
|
||||
(UIPEthernetClass::packetstate & UIPETHERNET_SENDPACKET ? UIP_IPH_LEN + UIP_LLH_LEN + UIP_SENDBUFFER_OFFSET : UIP_IPH_LEN + UIP_LLH_LEN) + upper_layer_memlen,
|
||||
upper_layer_len - upper_layer_memlen
|
||||
);
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
#if UIP_UDP
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::upper_layer_chksum(uint8_t proto) DEBUG:uip_packet("));
|
||||
#else
|
||||
LogObject.uart_send_str(F("uip_tcpchksum(void) DEBUG:uip_packet("));
|
||||
#endif
|
||||
LogObject.uart_send_dec(UIPEthernetClass::uip_packet);
|
||||
LogObject.uart_send_str(F(")["));
|
||||
LogObject.uart_send_dec(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen);
|
||||
LogObject.uart_send_str(F("-"));
|
||||
LogObject.uart_send_dec(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_len);
|
||||
LogObject.uart_send_str(F("]: "));
|
||||
LogObject.uart_send_hexln(htons(sum));
|
||||
#endif
|
||||
}
|
||||
return (sum == 0) ? 0xffff : htons(sum);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
uip_ipchksum(void)
|
||||
{
|
||||
return UIPEthernet.ipchksum();
|
||||
}
|
||||
|
||||
#if UIP_UDP
|
||||
uint16_t
|
||||
uip_tcpchksum(void)
|
||||
{
|
||||
uint16_t sum = UIPEthernet.upper_layer_chksum(UIP_PROTO_TCP);
|
||||
return sum;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
uip_udpchksum(void)
|
||||
{
|
||||
uint16_t sum = UIPEthernet.upper_layer_chksum(UIP_PROTO_UDP);
|
||||
return sum;
|
||||
}
|
||||
#endif
|
@ -0,0 +1,166 @@
|
||||
/*
|
||||
UIPEthernet.h - Arduino implementation of a uIP wrapper class.
|
||||
Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
|
||||
All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef UIPETHERNET_H
|
||||
#define UIPETHERNET_H
|
||||
|
||||
#include "ethernet_comp.h"
|
||||
#if defined(__MBED__)
|
||||
#include <mbed.h>
|
||||
#endif
|
||||
#if defined(ARDUINO)
|
||||
#include <Arduino.h>
|
||||
#if defined(__STM32F3__) || (!defined(ARDUINO_ARCH_STM32) && defined(STM32F3)) || defined(__RFduino__)
|
||||
#include "mbed/IPAddress.h"
|
||||
#else
|
||||
#include "IPAddress.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "utility/Enc28J60Network.h"
|
||||
#include "utility/uipopt.h"
|
||||
#include "Dhcp.h"
|
||||
#if UIP_UDP
|
||||
#include "UIPUdp.h"
|
||||
#endif
|
||||
#include "UIPClient.h"
|
||||
#include "UIPServer.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "utility/uip.h"
|
||||
}
|
||||
|
||||
#define UIPETHERNET_FREEPACKET 1
|
||||
#define UIPETHERNET_SENDPACKET 2
|
||||
#define UIPETHERNET_BUFFERREAD 4
|
||||
|
||||
#define uip_ip_addr(addr, ip) do { \
|
||||
((u16_t *)(addr))[0] = HTONS(((ip[0]) << 8) | (ip[1])); \
|
||||
((u16_t *)(addr))[1] = HTONS(((ip[2]) << 8) | (ip[3])); \
|
||||
} while(0)
|
||||
|
||||
#define ip_addr_uip(a) IPAddress(a[0] & 0xFF, a[0] >> 8 , a[1] & 0xFF, a[1] >> 8) //TODO this is not IPV6 capable
|
||||
|
||||
#define uip_seteth_addr(eaddr) do {uip_ethaddr.addr[0] = eaddr[0]; \
|
||||
uip_ethaddr.addr[1] = eaddr[1];\
|
||||
uip_ethaddr.addr[2] = eaddr[2];\
|
||||
uip_ethaddr.addr[3] = eaddr[3];\
|
||||
uip_ethaddr.addr[4] = eaddr[4];\
|
||||
uip_ethaddr.addr[5] = eaddr[5];} while(0)
|
||||
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
enum EthernetLinkStatus {
|
||||
Unknown,
|
||||
LinkON,
|
||||
LinkOFF
|
||||
};
|
||||
|
||||
enum EthernetHardwareStatus {
|
||||
EthernetNoHardware,
|
||||
EthernetW5100,
|
||||
EthernetW5200,
|
||||
EthernetW5500,
|
||||
EthernetENC28J60 = 10
|
||||
};
|
||||
|
||||
class UIPEthernetClass
|
||||
{
|
||||
public:
|
||||
UIPEthernetClass();
|
||||
|
||||
void init(const uint8_t pin);
|
||||
|
||||
int begin(const uint8_t* mac);
|
||||
void begin(const uint8_t* mac, IPAddress ip);
|
||||
void begin(const uint8_t* mac, IPAddress ip, IPAddress dns);
|
||||
void begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway);
|
||||
void begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
|
||||
|
||||
// maintain() must be called at regular intervals to process the incoming serial
|
||||
// data and issue IP events to the sketch. It does not return until all IP
|
||||
// events have been processed. Renews dhcp-lease if required.
|
||||
int maintain();
|
||||
|
||||
EthernetLinkStatus linkStatus();
|
||||
EthernetHardwareStatus hardwareStatus();
|
||||
|
||||
// KH add to have similar function to Ethernet lib
|
||||
// Certainly we can use void macAddress(uint8_t mac[]) to read from W5x00.
|
||||
void MACAddress(uint8_t *mac_address)
|
||||
{
|
||||
memcpy(mac_address, _mac_address, sizeof(_mac_address));
|
||||
}
|
||||
//////
|
||||
|
||||
IPAddress localIP();
|
||||
IPAddress subnetMask();
|
||||
IPAddress gatewayIP();
|
||||
IPAddress dnsServerIP();
|
||||
|
||||
private:
|
||||
|
||||
// KH add to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
uint8_t _mac_address[6] ={0,};
|
||||
//////
|
||||
|
||||
static memhandle in_packet;
|
||||
static memhandle uip_packet;
|
||||
static uint8_t uip_hdrlen;
|
||||
static uint8_t packetstate;
|
||||
|
||||
static IPAddress _dnsServerAddress;
|
||||
#if UIP_UDP
|
||||
static DhcpClass* _dhcp;
|
||||
#endif
|
||||
static unsigned long periodic_timer;
|
||||
|
||||
static void netInit(const uint8_t* mac);
|
||||
static void configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
|
||||
|
||||
static void tick();
|
||||
|
||||
static bool network_send();
|
||||
|
||||
friend class UIPServer;
|
||||
|
||||
friend class UIPClient;
|
||||
|
||||
friend class UIPUDP;
|
||||
|
||||
static uint16_t chksum(uint16_t sum, const uint8_t* data, uint16_t len);
|
||||
static uint16_t ipchksum(void);
|
||||
#if UIP_UDP
|
||||
static uint16_t upper_layer_chksum(uint8_t proto);
|
||||
#endif
|
||||
friend uint16_t uip_ipchksum(void);
|
||||
friend uint16_t uip_tcpchksum(void);
|
||||
friend uint16_t uip_udpchksum(void);
|
||||
|
||||
friend void uipclient_appcall(void);
|
||||
friend void uipudp_appcall(void);
|
||||
|
||||
#if UIP_CONF_IPV6
|
||||
uint16_t uip_icmp6chksum(void);
|
||||
#endif /* UIP_CONF_IPV6 */
|
||||
};
|
||||
|
||||
extern UIPEthernetClass UIPEthernet;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,337 @@
|
||||
/*
|
||||
Enc28J60NetworkClass.h
|
||||
UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface.
|
||||
|
||||
Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
|
||||
All rights reserved.
|
||||
|
||||
inspired by enc28j60.c file from the AVRlib library by Pascal Stang.
|
||||
For AVRlib See http://www.procyonengineering.com/
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef Enc28J60Network_H_
|
||||
#define Enc28J60Network_H_
|
||||
|
||||
// KH mod
|
||||
#if defined(ESP32)
|
||||
//pin SS already defined in ESP32 as pin 5, don't use this as conflict with SPIFFS, EEPROM, etc.
|
||||
// Use in GPIO13
|
||||
#warning ENC28J60Network.h => use ESP32, change ENC28J60_CONTROL_CS/SS_PIN_DEFAULT to GPIO13, MOSI(23), MISO(19), SCK(18)
|
||||
#define ENC28J60_CONTROL_CS 13
|
||||
#endif
|
||||
|
||||
// KH, For nRF52
|
||||
#if ( defined(NRF52840_FEATHER) || defined(NRF52832_FEATHER) || defined(NRF52_SERIES) || defined(ARDUINO_NRF52_ADAFRUIT) || \
|
||||
defined(NRF52840_FEATHER_SENSE) || defined(NRF52840_ITSYBITSY) || defined(NRF52840_CIRCUITPLAY) || defined(NRF52840_CLUE) || \
|
||||
defined(NRF52840_METRO) || defined(NRF52840_PCA10056) || defined(PARTICLE_XENON) || defined(NINA_B302_ublox) || defined(NINA_B112_ublox) )
|
||||
#include <SPI.h>
|
||||
#define ENC28J60_USE_SPILIB 1
|
||||
|
||||
#ifndef USE_THIS_SS_PIN
|
||||
// default to pin 10
|
||||
#define ENC28J60_CONTROL_CS 10
|
||||
#else
|
||||
#warning Using USE_THIS_SS_PIN in Enc28J60Network.h for nRF52
|
||||
#define ENC28J60_CONTROL_CS USE_THIS_SS_PIN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// KH, For SAMD21/SAMD51
|
||||
#if ( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
|
||||
|| defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
|
||||
|| defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(__SAMD21G18A__) \
|
||||
|| defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD21E18A__) || defined(__SAMD51__) || defined(__SAMD51J20A__) || defined(__SAMD51J19A__) \
|
||||
|| defined(__SAMD51G19A__) || defined(__SAMD51P19A__) || defined(__SAMD21G18A__) )
|
||||
#include <SPI.h>
|
||||
#define ENC28J60_USE_SPILIB 1
|
||||
|
||||
#ifndef USE_THIS_SS_PIN
|
||||
// default to pin 10
|
||||
#define ENC28J60_CONTROL_CS 10
|
||||
#else
|
||||
#warning Using USE_THIS_SS_PIN in Enc28J60Network.h for SAMD
|
||||
#define ENC28J60_CONTROL_CS USE_THIS_SS_PIN
|
||||
#endif
|
||||
#endif
|
||||
//////
|
||||
|
||||
#include "mempool.h"
|
||||
#if defined(__MBED__)
|
||||
#include <mbed.h>
|
||||
//UIPEthernet(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS);
|
||||
#if defined(TARGET_LPC1768)
|
||||
#define SPI_MOSI p11
|
||||
#define SPI_MISO p12
|
||||
#define SPI_SCK p13
|
||||
#define SPI_CS p8
|
||||
#elif defined(TARGET_LPC1114)
|
||||
#define SPI_MOSI dp2
|
||||
#define SPI_MISO dp1
|
||||
#define SPI_SCK dp6
|
||||
#define SPI_CS dp25
|
||||
#elif defined(TARGET_LPC11U68)
|
||||
#define SPI_MOSI P0_9
|
||||
#define SPI_MISO P0_8
|
||||
#define SPI_SCK P1_29
|
||||
#define SPI_CS P0_2
|
||||
#elif defined(TARGET_NUCLEO_F103RB) || defined(TARGET_NUCLEO_L152RE) || defined(TARGET_NUCLEO_F030R8) \
|
||||
|| defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F302R8) || defined(TARGET_NUCLEO_L053R8) \
|
||||
|| defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F334R8) || defined(TARGET_NUCLEO_F072RB) \
|
||||
|| defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F070RB)
|
||||
#define SPI_MOSI D4
|
||||
#define SPI_MISO D5
|
||||
#define SPI_SCK D3
|
||||
#define SPI_CS D2
|
||||
#endif
|
||||
#define ENC28J60_CONTROL_CS SPI_CS
|
||||
#endif
|
||||
|
||||
#if defined(STM32F3) || defined(STM32F2) //This is workaround for stm32duino STM32F2, and adafruit wiced feather STM32F2
|
||||
#define BOARD_SPI1_NSS_PIN PA4
|
||||
#define BOARD_SPI1_SCK_PIN PA5
|
||||
#define BOARD_SPI1_MISO_PIN PA6
|
||||
#define BOARD_SPI1_MOSI_PIN PA7
|
||||
#endif //This is workaround for stm32duino STM32F3, and adafruit wiced feather STM32F2
|
||||
|
||||
#if defined(BOARD_discovery_f4)
|
||||
#define __STM32F4__
|
||||
#endif
|
||||
#if defined(__MK20DX128__) || defined(__MKL26Z64__)
|
||||
#include <SPIFIFO.h>
|
||||
#endif
|
||||
|
||||
#if !defined(ENC28J60_CONTROL_CS)
|
||||
#if defined(__AVR__) || defined(ESP8266) || defined(__RFduino__)
|
||||
// Arduino Uno (__AVR__) SS defined to pin 10
|
||||
// Arduino Leonardo (ARDUINO_AVR_LEONARDO) SS defined to LED_BUILTIN_RX (17)
|
||||
// Arduino Mega(__AVR_ATmega2560__) SS defined to pin 53
|
||||
// ESP8266 (ESP8266) SS defined to pin 15
|
||||
#if defined(ARDUINO_AVR_LEONARDO) || defined(ARDUINO_AVR_MICRO)
|
||||
#define ENC28J60_CONTROL_CS PIN_A10
|
||||
#warning "Using LEONARDO borad PIN_A10 for ENC28J60_CONTROL_CS. Use UIPEthernet::init(uint8_t) to change it."
|
||||
#else
|
||||
#define ENC28J60_CONTROL_CS SS
|
||||
#endif
|
||||
#elif defined(ARDUINO_ARCH_AMEBA) //Defined SS to pin 10
|
||||
#define ENC28J60_CONTROL_CS SS //PC_0 A5 10
|
||||
#elif defined(ARDUINO_ARCH_SAM)
|
||||
// Arduino Due (ARDUINO_ARCH_SAM) BOARD_SPI_DEFAULT_SS (SS3) defined to pin 78
|
||||
//#define ENC28J60_CONTROL_CS BOARD_SPI_DEFAULT_SS
|
||||
#define ENC28J60_CONTROL_CS BOARD_SPI_SS0
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
#define ENC28J60_CONTROL_CS SS
|
||||
#elif defined(__ARDUINO_ARC__) //Intel ARC32 Genuino 101
|
||||
#define ENC28J60_CONTROL_CS SS
|
||||
#elif defined(__RFduino__) //RFduino
|
||||
#define ENC28J60_CONTROL_CS SS
|
||||
#elif defined(ARDUINO_ARCH_STM32) // STM32duino core
|
||||
#define ENC28J60_CONTROL_CS SS
|
||||
#elif defined(ARDUINO_ARCH_ESP32) // arduino-esp32
|
||||
#define ENC28J60_CONTROL_CS SS
|
||||
#elif defined(STM32_MCU_SERIES) || defined(__STM32F1__) || defined(__STM32F3__) || defined(STM32F3) || defined(__STM32F4__) || defined(STM32F2)
|
||||
#if defined(BOARD_SPI1_NSS_PIN)
|
||||
#define ENC28J60_CONTROL_CS BOARD_SPI1_NSS_PIN
|
||||
#elif defined(ARDUINO_STM32F4_NETDUINO2PLUS)
|
||||
#define ENC28J60_CONTROL_CS PC8
|
||||
#else
|
||||
#define ENC28J60_CONTROL_CS SPI.nssPin()
|
||||
//#define ENC28J60_CONTROL_CS PA4
|
||||
#endif
|
||||
#elif defined(__MK20DX128__) || defined(__MKL26Z64__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__)
|
||||
#define ENC28J60_CONTROL_CS PIN_SPI_SS
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(ENC28J60_CONTROL_CS)
|
||||
#warning "Default ENC28J60_CONTROL_CS could not be defined! Use UIPEthernet::init(uint8_t) to set it."
|
||||
#define ENC28J60_CONTROL_CS 0
|
||||
#endif
|
||||
|
||||
extern uint8_t ENC28J60ControlCS;
|
||||
|
||||
#if !defined(SPI_MOSI)
|
||||
#if defined(__AVR__) || defined(ESP8266) || defined(__RFduino__)
|
||||
#define SPI_MOSI MOSI
|
||||
#elif defined(ARDUINO_ARCH_AMEBA)
|
||||
#define SPI_MOSI 11 //PC_2
|
||||
#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
|
||||
#define SPI_MOSI PIN_SPI_MOSI
|
||||
#elif defined(__ARDUINO_ARC__) //Intel ARC32 Genuino 101
|
||||
#define SPI_MOSI MOSI
|
||||
#elif defined(__RFduino__) //RFduino
|
||||
#define SPI_MOSI MOSI
|
||||
#elif defined(ARDUINO_ARCH_STM32) // STM32duino core
|
||||
#define SPI_MOSI MOSI
|
||||
#elif defined(ARDUINO_ARCH_ESP32) // arduino-esp32
|
||||
#define SPI_MOSI MOSI
|
||||
#elif defined(STM32_MCU_SERIES) || defined(__STM32F1__) || defined(__STM32F3__) || defined(STM32F3) || defined(__STM32F4__) || defined(STM32F2)
|
||||
#if defined(BOARD_SPI1_MOSI_PIN)
|
||||
#define SPI_MOSI BOARD_SPI1_MOSI_PIN
|
||||
#else
|
||||
#define SPI_MOSI SPI.mosiPin()
|
||||
#endif
|
||||
#elif defined(__MK20DX128__) || defined(__MKL26Z64__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__)
|
||||
#define SPI_MOSI PIN_SPI_MOSI
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SPI_MOSI)
|
||||
// KH mod
|
||||
//#error "Not defined SPI_MOSI!"
|
||||
#define SPI_MOSI MOSI
|
||||
//////
|
||||
#endif
|
||||
|
||||
#if !defined(SPI_MISO)
|
||||
#if defined(__AVR__) || defined(ESP8266) || defined(__RFduino__)
|
||||
#define SPI_MISO MISO
|
||||
#elif defined(ARDUINO_ARCH_AMEBA)
|
||||
#define SPI_MISO 12 //PC_3
|
||||
#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
|
||||
#define SPI_MISO PIN_SPI_MISO
|
||||
#elif defined(__ARDUINO_ARC__) //Intel ARC32 Genuino 101
|
||||
#define SPI_MISO MISO
|
||||
#elif defined(__RFduino__) //RFduino
|
||||
#define SPI_MISO MISO
|
||||
#elif defined(ARDUINO_ARCH_STM32) // STM32duino core
|
||||
#define SPI_MISO MISO
|
||||
#elif defined(ARDUINO_ARCH_ESP32) // arduino-esp32
|
||||
#define SPI_MISO MISO
|
||||
#elif defined(STM32_MCU_SERIES) || defined(__STM32F1__) || defined(__STM32F3__) || defined(STM32F3) || defined(__STM32F4__) || defined(STM32F2)
|
||||
#if defined(BOARD_SPI1_MISO_PIN)
|
||||
#define SPI_MISO BOARD_SPI1_MISO_PIN
|
||||
#else
|
||||
#define SPI_MISO SPI.misoPin()
|
||||
#endif
|
||||
#elif defined(__MK20DX128__) || defined(__MKL26Z64__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__)
|
||||
#define SPI_MISO PIN_SPI_MISO
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SPI_MISO)
|
||||
// KH mod
|
||||
//#error "Not defined SPI_MISO!"
|
||||
#define SPI_MISO MISO
|
||||
//////
|
||||
#endif
|
||||
#if !defined(SPI_SCK)
|
||||
#if defined(__AVR__) || defined(ESP8266) || defined(__RFduino__)
|
||||
#define SPI_SCK SCK
|
||||
#elif defined(ARDUINO_ARCH_AMEBA)
|
||||
#define SPI_SCK 13 //PC_1 A4
|
||||
#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
|
||||
#define SPI_SCK PIN_SPI_SCK
|
||||
#elif defined(__ARDUINO_ARC__) //Intel ARC32 Genuino 101
|
||||
#define SPI_SCK SCK
|
||||
#elif defined(__RFduino__) //RFduino
|
||||
#define SPI_SCK SCK
|
||||
#elif defined(ARDUINO_ARCH_STM32) // STM32duino core
|
||||
#define SPI_SCK SCK
|
||||
#elif defined(ARDUINO_ARCH_ESP32) // arduino-esp32
|
||||
#define SPI_SCK SCK
|
||||
#elif defined(STM32_MCU_SERIES) || defined(__STM32F1__) || defined(__STM32F3__) || defined(STM32F3) || defined(__STM32F4__) || defined(STM32F2)
|
||||
#if defined(BOARD_SPI1_SCK_PIN)
|
||||
#define SPI_SCK BOARD_SPI1_SCK_PIN
|
||||
#else
|
||||
#define SPI_SCK SPI.sckPin()
|
||||
#endif
|
||||
#elif defined(__MK20DX128__) || defined(__MKL26Z64__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__)
|
||||
#define SPI_SCK PIN_SPI_SCK
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SPI_SCK)
|
||||
// KH, For nRF52
|
||||
//#error "Not defined SPI_SCK!"
|
||||
#define SPI_SCK SCK
|
||||
//////
|
||||
#endif
|
||||
|
||||
#if defined(__MBED__) || defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) || defined(__ARDUINO_ARC__) || defined(__STM32F1__) || defined(__STM32F3__) || defined(STM32F3) || defined(__STM32F4__) || defined(STM32F2) || defined(ESP8266) || defined(ARDUINO_ARCH_AMEBA) || defined(__MK20DX128__) || defined(__MKL26Z64__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__) || defined(__RFduino__) || defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
|
||||
#if defined(ARDUINO) && (!defined(ARDUINO_ARCH_STM32) && defined(STM32F3))
|
||||
#include "HardwareSPI.h"
|
||||
#else
|
||||
#include <SPI.h>
|
||||
#endif
|
||||
#define ENC28J60_USE_SPILIB 1
|
||||
#endif
|
||||
|
||||
#define UIP_RECEIVEBUFFERHANDLE 0xff
|
||||
|
||||
#define UIP_SENDBUFFER_PADDING 7
|
||||
#define UIP_SENDBUFFER_OFFSET 1
|
||||
|
||||
/*
|
||||
* Empfangen von ip-header, arp etc...
|
||||
* wenn tcp/udp -> tcp/udp-callback -> assign new packet to connection
|
||||
*/
|
||||
|
||||
#define TX_COLLISION_RETRY_COUNT 10
|
||||
|
||||
class Enc28J60Network : public MemoryPool
|
||||
{
|
||||
|
||||
private:
|
||||
static uint16_t nextPacketPtr;
|
||||
static uint8_t bank;
|
||||
static uint8_t erevid;
|
||||
|
||||
static struct memblock receivePkt;
|
||||
|
||||
static bool broadcast_enabled; //!< True if broadcasts enabled (used to allow temporary disable of broadcast for DHCP or other internal functions)
|
||||
|
||||
static uint8_t readOp(uint8_t op, uint8_t address);
|
||||
static void writeOp(uint8_t op, uint8_t address, uint8_t data);
|
||||
static uint16_t setReadPtr(memhandle handle, memaddress position, uint16_t len);
|
||||
static void setERXRDPT(void);
|
||||
static void readBuffer(uint16_t len, uint8_t* data);
|
||||
static void writeBuffer(uint16_t len, uint8_t* data);
|
||||
static uint8_t readByte(uint16_t addr);
|
||||
static void writeByte(uint16_t addr, uint8_t data);
|
||||
static void setBank(uint8_t address);
|
||||
static uint8_t readReg(uint8_t address);
|
||||
static void writeReg(uint8_t address, uint8_t data);
|
||||
static void writeRegPair(uint8_t address, uint16_t data);
|
||||
static void phyWrite(uint8_t address, uint16_t data);
|
||||
static uint16_t phyRead(uint8_t address);
|
||||
static void clkout(uint8_t clk);
|
||||
|
||||
static void enableBroadcast (bool temporary);
|
||||
static void disableBroadcast (bool temporary);
|
||||
static void enableMulticast (void);
|
||||
static void disableMulticast (void);
|
||||
|
||||
static uint8_t readRegByte (uint8_t address);
|
||||
static void writeRegByte (uint8_t address, uint8_t data);
|
||||
|
||||
friend void enc28J60_mempool_block_move_callback(memaddress,memaddress,memaddress);
|
||||
|
||||
public:
|
||||
|
||||
void powerOn(void);
|
||||
void powerOff(void);
|
||||
static uint8_t geterevid(void);
|
||||
uint16_t PhyStatus(void);
|
||||
static bool linkStatus(void);
|
||||
|
||||
static void init(uint8_t* macaddr);
|
||||
static memhandle receivePacket(void);
|
||||
static void freePacket(void);
|
||||
static memaddress blockSize(memhandle handle);
|
||||
static bool sendPacket(memhandle handle);
|
||||
static uint16_t readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len);
|
||||
static uint16_t writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len);
|
||||
static void copyPacket(memhandle dest, memaddress dest_pos, memhandle src, memaddress src_pos, uint16_t len);
|
||||
static uint16_t chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len);
|
||||
};
|
||||
|
||||
#endif /* Enc28J60NetworkClass_H_ */
|
@ -0,0 +1,641 @@
|
||||
/*
|
||||
UIPEthernet.cpp - Arduino implementation of a uIP wrapper class.
|
||||
Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
|
||||
All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(ARDUINO)
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
#if defined(__MBED__)
|
||||
#include <mbed.h>
|
||||
#include "mbed/millis.h"
|
||||
#endif
|
||||
#include "UIPEthernet.h"
|
||||
#include "utility/logging.h"
|
||||
#include "utility/Enc28J60Network.h"
|
||||
|
||||
#include "UIPUdp.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "utility/uipopt.h"
|
||||
#include "utility/uip.h"
|
||||
#include "utility/uip_arp.h"
|
||||
#include "utility/uip_timer.h"
|
||||
}
|
||||
|
||||
#define ETH_HDR ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
|
||||
memhandle UIPEthernetClass::in_packet(NOBLOCK);
|
||||
memhandle UIPEthernetClass::uip_packet(NOBLOCK);
|
||||
uint8_t UIPEthernetClass::uip_hdrlen(0);
|
||||
uint8_t UIPEthernetClass::packetstate(0);
|
||||
|
||||
unsigned long UIPEthernetClass::periodic_timer;
|
||||
|
||||
IPAddress UIPEthernetClass::_dnsServerAddress;
|
||||
#if UIP_UDP
|
||||
DhcpClass* UIPEthernetClass::_dhcp(NULL);
|
||||
static DhcpClass s_dhcp; // Placing this instance here is saving 40K to final *.bin (see bug below)
|
||||
#endif
|
||||
|
||||
// Because uIP isn't encapsulated within a class we have to use global
|
||||
// variables, so we can only have one TCP/IP stack per program.
|
||||
|
||||
UIPEthernetClass::UIPEthernetClass()
|
||||
{
|
||||
}
|
||||
|
||||
void UIPEthernetClass::init(const uint8_t pin)
|
||||
{
|
||||
ENC28J60ControlCS = pin;
|
||||
}
|
||||
|
||||
#if UIP_UDP
|
||||
int
|
||||
UIPEthernetClass::begin(const uint8_t* mac)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var _mac_address
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::begin(const uint8_t* mac) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
//static DhcpClass s_dhcp; // <-- this is a bug !
|
||||
// I leave it there commented for history. It is bring all GCC "new" memory allocation code, making the *.bin almost 40K bigger. I've move it globally.
|
||||
_dhcp = &s_dhcp;
|
||||
// Initialise the basic info
|
||||
netInit(mac);
|
||||
|
||||
// Now try to get our config info from a DHCP server
|
||||
int ret = _dhcp->beginWithDHCP((uint8_t*)mac);
|
||||
if(ret == 1)
|
||||
{
|
||||
// We've successfully found a DHCP server and got our configuration info, so set things
|
||||
// accordingly
|
||||
configure(_dhcp->getLocalIp(),_dhcp->getDnsServerIp(),_dhcp->getGatewayIp(),_dhcp->getSubnetMask());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var _mac_address
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
IPAddress dns = ip;
|
||||
dns[3] = 1;
|
||||
begin(mac, ip, dns);
|
||||
}
|
||||
|
||||
void
|
||||
UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var _mac_address
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
IPAddress gateway = ip;
|
||||
gateway[3] = 1;
|
||||
begin(mac, ip, dns, gateway);
|
||||
}
|
||||
|
||||
void
|
||||
UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var _mac_address
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
begin(mac, ip, dns, gateway, subnet);
|
||||
}
|
||||
|
||||
void
|
||||
UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)
|
||||
{
|
||||
// KH mod to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
// Now store to private var _mac_address
|
||||
//uint8_t _mac_address[6] ={0,};
|
||||
memcpy(_mac_address, mac, sizeof(_mac_address));
|
||||
//////
|
||||
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
netInit(mac);
|
||||
configure(ip,dns,gateway,subnet);
|
||||
}
|
||||
|
||||
int UIPEthernetClass::maintain(){
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::maintain() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
tick();
|
||||
int rc = DHCP_CHECK_NONE;
|
||||
#if UIP_UDP
|
||||
if(_dhcp != NULL){
|
||||
//we have a pointer to dhcp, use it
|
||||
rc = _dhcp->checkLease();
|
||||
switch ( rc ){
|
||||
case DHCP_CHECK_NONE:
|
||||
//nothing done
|
||||
break;
|
||||
case DHCP_CHECK_RENEW_OK:
|
||||
case DHCP_CHECK_REBIND_OK:
|
||||
//we might have got a new IP.
|
||||
configure(_dhcp->getLocalIp(),_dhcp->getDnsServerIp(),_dhcp->getGatewayIp(),_dhcp->getSubnetMask());
|
||||
break;
|
||||
default:
|
||||
//this is actually a error, it will retry though
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
|
||||
EthernetLinkStatus UIPEthernetClass::linkStatus()
|
||||
{
|
||||
if (!Enc28J60.geterevid())
|
||||
return Unknown;
|
||||
return Enc28J60.linkStatus() ? LinkON : LinkOFF;
|
||||
}
|
||||
|
||||
IPAddress UIPEthernetClass::localIP()
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::localIP() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
IPAddress ret;
|
||||
uip_ipaddr_t a;
|
||||
uip_gethostaddr(a);
|
||||
return ip_addr_uip(a);
|
||||
}
|
||||
|
||||
IPAddress UIPEthernetClass::subnetMask()
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::subnetMask() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
IPAddress ret;
|
||||
uip_ipaddr_t a;
|
||||
uip_getnetmask(a);
|
||||
return ip_addr_uip(a);
|
||||
}
|
||||
|
||||
IPAddress UIPEthernetClass::gatewayIP()
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::gatewayIP() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
IPAddress ret;
|
||||
uip_ipaddr_t a;
|
||||
uip_getdraddr(a);
|
||||
return ip_addr_uip(a);
|
||||
}
|
||||
|
||||
IPAddress UIPEthernetClass::dnsServerIP()
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::dnsServerIP() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
return _dnsServerAddress;
|
||||
}
|
||||
|
||||
void
|
||||
UIPEthernetClass::tick()
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::tick() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
if (Enc28J60Network::geterevid()==0)
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_ERR
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::tick() ERROR:EREVID=0 -> Not found ENC28j60 device !! Function ended !!"));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#if defined(ESP8266)
|
||||
wdt_reset();
|
||||
#endif
|
||||
if (in_packet == NOBLOCK)
|
||||
{
|
||||
in_packet = Enc28J60Network::receivePacket();
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
if (in_packet != NOBLOCK)
|
||||
{
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::tick() DEBUG:receivePacket: "));
|
||||
LogObject.uart_send_decln(in_packet);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (in_packet != NOBLOCK)
|
||||
{
|
||||
packetstate = UIPETHERNET_FREEPACKET;
|
||||
uip_len = Enc28J60Network::blockSize(in_packet);
|
||||
if (uip_len > 0)
|
||||
{
|
||||
Enc28J60Network::readPacket(in_packet,0,(uint8_t*)uip_buf,UIP_BUFSIZE);
|
||||
if (ETH_HDR ->type == HTONS(UIP_ETHTYPE_IP))
|
||||
{
|
||||
uip_packet = in_packet; //required for upper_layer_checksum of in_packet!
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: "));
|
||||
LogObject.uart_send_decln(uip_len);
|
||||
#endif
|
||||
uip_arp_ipin();
|
||||
uip_input();
|
||||
if (uip_len > 0)
|
||||
{
|
||||
uip_arp_out();
|
||||
network_send();
|
||||
}
|
||||
}
|
||||
else if (ETH_HDR ->type == HTONS(UIP_ETHTYPE_ARP))
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::tick() DEBUG:readPacket type ARP, uip_len: "));
|
||||
LogObject.uart_send_decln(uip_len);
|
||||
#endif
|
||||
uip_arp_arpin();
|
||||
if (uip_len > 0)
|
||||
{
|
||||
network_send();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (in_packet != NOBLOCK && (packetstate & UIPETHERNET_FREEPACKET))
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::tick() DEBUG:freeing packet: "));
|
||||
LogObject.uart_send_decln(in_packet);
|
||||
#endif
|
||||
Enc28J60Network::freePacket();
|
||||
in_packet = NOBLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long now = millis();
|
||||
|
||||
#if UIP_CLIENT_TIMER >= 0
|
||||
bool periodic = (long)( now - periodic_timer ) >= 0;
|
||||
for (int i = 0; i < UIP_CONNS; i++)
|
||||
{
|
||||
#else
|
||||
if ((long)( now - periodic_timer ) >= 0)
|
||||
{
|
||||
periodic_timer = now + UIP_PERIODIC_TIMER;
|
||||
|
||||
for (int i = 0; i < UIP_CONNS; i++)
|
||||
{
|
||||
#endif
|
||||
|
||||
uip_conn = &uip_conns[i];
|
||||
|
||||
#if UIP_CLIENT_TIMER >= 0
|
||||
if (periodic)
|
||||
{
|
||||
#endif
|
||||
|
||||
uip_process(UIP_TIMER);
|
||||
|
||||
#if UIP_CLIENT_TIMER >= 0
|
||||
}
|
||||
else
|
||||
{
|
||||
if (uip_conn!=NULL)
|
||||
{
|
||||
if (((uip_userdata_t*)uip_conn->appstate)!=NULL)
|
||||
{
|
||||
if ((long)( now - ((uip_userdata_t*)uip_conn->appstate)->timer) >= 0)
|
||||
{
|
||||
uip_process(UIP_POLL_REQUEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::tick() DEBUG_V3:((uip_userdata_t*)uip_conn->appstate) is NULL"));
|
||||
#endif
|
||||
if ((long)( now - ((uip_userdata_t*)uip_conn)->timer) >= 0)
|
||||
{
|
||||
uip_process(UIP_POLL_REQUEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_ERR
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::tick() ERROR:uip_conn is NULL"));
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// If the above function invocation resulted in data that
|
||||
// should be sent out on the Enc28J60Network, the global variable
|
||||
// uip_len is set to a value > 0.
|
||||
if (uip_len > 0)
|
||||
{
|
||||
uip_arp_out();
|
||||
network_send();
|
||||
}
|
||||
}
|
||||
#if UIP_CLIENT_TIMER >= 0
|
||||
if (periodic)
|
||||
{
|
||||
periodic_timer = now + UIP_PERIODIC_TIMER;
|
||||
#endif
|
||||
#if UIP_UDP
|
||||
for (int i = 0; i < UIP_UDP_CONNS; i++)
|
||||
{
|
||||
uip_udp_periodic(i);
|
||||
// If the above function invocation resulted in data that
|
||||
// should be sent out on the Enc28J60Network, the global variable
|
||||
// uip_len is set to a value > 0. */
|
||||
if (uip_len > 0)
|
||||
{
|
||||
UIPUDP::_send((uip_udp_userdata_t *)(uip_udp_conns[i].appstate));
|
||||
}
|
||||
}
|
||||
#endif /* UIP_UDP */
|
||||
}
|
||||
}
|
||||
|
||||
bool UIPEthernetClass::network_send()
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::network_send() DEBUG_V3:Function started"));
|
||||
#endif
|
||||
if (packetstate & UIPETHERNET_SENDPACKET)
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::network_send() DEBUG:uip_packet: "));
|
||||
LogObject.uart_send_dec(uip_packet);
|
||||
LogObject.uart_send_str(F(", hdrlen: "));
|
||||
LogObject.uart_send_decln(uip_hdrlen);
|
||||
#endif
|
||||
Enc28J60Network::writePacket(uip_packet,0,uip_buf,uip_hdrlen);
|
||||
packetstate &= ~ UIPETHERNET_SENDPACKET;
|
||||
goto sendandfree;
|
||||
}
|
||||
uip_packet = Enc28J60Network::allocBlock(uip_len);
|
||||
if (uip_packet != NOBLOCK)
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): "));
|
||||
LogObject.uart_send_dec(uip_len);
|
||||
LogObject.uart_send_str(F(", packet: "));
|
||||
LogObject.uart_send_decln(uip_packet);
|
||||
#endif
|
||||
Enc28J60Network::writePacket(uip_packet,0,uip_buf,uip_len);
|
||||
goto sendandfree;
|
||||
}
|
||||
return false;
|
||||
sendandfree:
|
||||
Enc28J60Network::sendPacket(uip_packet);
|
||||
Enc28J60Network::freeBlock(uip_packet);
|
||||
uip_packet = NOBLOCK;
|
||||
return true;
|
||||
}
|
||||
|
||||
void UIPEthernetClass::netInit(const uint8_t* mac) {
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::netInit(const uint8_t* mac) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
periodic_timer = millis() + UIP_PERIODIC_TIMER;
|
||||
|
||||
Enc28J60Network::init((uint8_t*)mac);
|
||||
uip_seteth_addr(mac);
|
||||
|
||||
uip_init();
|
||||
uip_arp_init();
|
||||
}
|
||||
|
||||
void UIPEthernetClass::configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) {
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
uip_ipaddr_t ipaddr;
|
||||
|
||||
uip_ip_addr(ipaddr, ip);
|
||||
uip_sethostaddr(ipaddr);
|
||||
|
||||
uip_ip_addr(ipaddr, gateway);
|
||||
uip_setdraddr(ipaddr);
|
||||
|
||||
uip_ip_addr(ipaddr, subnet);
|
||||
uip_setnetmask(ipaddr);
|
||||
|
||||
_dnsServerAddress = dns;
|
||||
}
|
||||
|
||||
UIPEthernetClass UIPEthernet;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint16_t
|
||||
UIPEthernetClass::chksum(uint16_t sum, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::chksum(uint16_t sum, const uint8_t *data, uint16_t len) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
uint16_t t;
|
||||
const uint8_t *dataptr;
|
||||
const uint8_t *last_byte;
|
||||
|
||||
dataptr = data;
|
||||
last_byte = data + len - 1;
|
||||
|
||||
while(dataptr < last_byte) { /* At least two more bytes */
|
||||
t = (dataptr[0] << 8) + dataptr[1];
|
||||
sum += t;
|
||||
if(sum < t) {
|
||||
sum++; /* carry */
|
||||
}
|
||||
dataptr += 2;
|
||||
}
|
||||
|
||||
if(dataptr == last_byte) {
|
||||
t = (dataptr[0] << 8) + 0;
|
||||
sum += t;
|
||||
if(sum < t) {
|
||||
sum++; /* carry */
|
||||
}
|
||||
}
|
||||
|
||||
/* Return sum in host byte order. */
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
uint16_t
|
||||
UIPEthernetClass::ipchksum(void)
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::ipchksum(void) DEBUG_V3:Function started"));
|
||||
#endif
|
||||
uint16_t sum;
|
||||
|
||||
sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
|
||||
return (sum == 0) ? 0xffff : htons(sum);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint16_t
|
||||
#if UIP_UDP
|
||||
UIPEthernetClass::upper_layer_chksum(uint8_t proto)
|
||||
#else
|
||||
uip_tcpchksum(void)
|
||||
#endif
|
||||
{
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG_V3
|
||||
#if UIP_UDP
|
||||
LogObject.uart_send_strln(F("UIPEthernetClass::upper_layer_chksum(uint8_t proto) DEBUG_V3:Function started"));
|
||||
#else
|
||||
LogObject.uart_send_strln(F("uip_tcpchksum(void) INFO:Function started"));
|
||||
#endif
|
||||
#endif
|
||||
uint16_t upper_layer_len;
|
||||
uint16_t sum;
|
||||
|
||||
#if UIP_CONF_IPV6
|
||||
upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);
|
||||
#else /* UIP_CONF_IPV6 */
|
||||
upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
|
||||
#endif /* UIP_CONF_IPV6 */
|
||||
|
||||
/* First sum pseudoheader. */
|
||||
|
||||
/* IP protocol and length fields. This addition cannot carry. */
|
||||
#if UIP_UDP
|
||||
sum = upper_layer_len + proto;
|
||||
#else
|
||||
sum = upper_layer_len + UIP_PROTO_TCP;
|
||||
#endif
|
||||
/* Sum IP source and destination addresses. */
|
||||
sum = UIPEthernetClass::chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
|
||||
|
||||
uint8_t upper_layer_memlen;
|
||||
#if UIP_UDP
|
||||
switch(proto)
|
||||
{
|
||||
// case UIP_PROTO_ICMP:
|
||||
// case UIP_PROTO_ICMP6:
|
||||
// upper_layer_memlen = upper_layer_len;
|
||||
// break;
|
||||
case UIP_PROTO_UDP:
|
||||
upper_layer_memlen = UIP_UDPH_LEN;
|
||||
break;
|
||||
default:
|
||||
// case UIP_PROTO_TCP:
|
||||
#endif
|
||||
upper_layer_memlen = (BUF->tcpoffset >> 4) << 2;
|
||||
#if UIP_UDP
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
sum = UIPEthernetClass::chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_memlen);
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
#if UIP_UDP
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::upper_layer_chksum(uint8_t proto) DEBUG:uip_buf["));
|
||||
#else
|
||||
LogObject.uart_send_str(F("uip_tcpchksum(void) DEBUG:uip_buf["));
|
||||
#endif
|
||||
LogObject.uart_send_dec(UIP_IPH_LEN + UIP_LLH_LEN);
|
||||
LogObject.uart_send_str(F("-"));
|
||||
LogObject.uart_send_dec(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen);
|
||||
LogObject.uart_send_str(F("]: "));
|
||||
LogObject.uart_send_hexln(htons(sum));
|
||||
#endif
|
||||
if (upper_layer_memlen < upper_layer_len)
|
||||
{
|
||||
sum = Enc28J60Network::chksum(
|
||||
sum,
|
||||
UIPEthernetClass::uip_packet,
|
||||
UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen,
|
||||
upper_layer_len - upper_layer_memlen
|
||||
);
|
||||
#if ACTLOGLEVEL>=LOG_DEBUG
|
||||
#if UIP_UDP
|
||||
LogObject.uart_send_str(F("UIPEthernetClass::upper_layer_chksum(uint8_t proto) DEBUG:uip_packet("));
|
||||
#else
|
||||
LogObject.uart_send_str(F("uip_tcpchksum(void) DEBUG:uip_packet("));
|
||||
#endif
|
||||
LogObject.uart_send_dec(UIPEthernetClass::uip_packet);
|
||||
LogObject.uart_send_str(F(")["));
|
||||
LogObject.uart_send_dec(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen);
|
||||
LogObject.uart_send_str(F("-"));
|
||||
LogObject.uart_send_dec(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_len);
|
||||
LogObject.uart_send_str(F("]: "));
|
||||
LogObject.uart_send_hexln(htons(sum));
|
||||
#endif
|
||||
}
|
||||
return (sum == 0) ? 0xffff : htons(sum);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
uip_ipchksum(void)
|
||||
{
|
||||
return UIPEthernet.ipchksum();
|
||||
}
|
||||
|
||||
#if UIP_UDP
|
||||
uint16_t
|
||||
uip_tcpchksum(void)
|
||||
{
|
||||
uint16_t sum = UIPEthernet.upper_layer_chksum(UIP_PROTO_TCP);
|
||||
return sum;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
uip_udpchksum(void)
|
||||
{
|
||||
uint16_t sum = UIPEthernet.upper_layer_chksum(UIP_PROTO_UDP);
|
||||
return sum;
|
||||
}
|
||||
#endif
|
@ -0,0 +1,158 @@
|
||||
/*
|
||||
UIPEthernet.h - Arduino implementation of a uIP wrapper class.
|
||||
Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
|
||||
All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef UIPETHERNET_H
|
||||
#define UIPETHERNET_H
|
||||
|
||||
#include "ethernet_comp.h"
|
||||
#if defined(__MBED__)
|
||||
#include <mbed.h>
|
||||
#endif
|
||||
#if defined(ARDUINO)
|
||||
#include <Arduino.h>
|
||||
#if defined(__STM32F3__) || defined(STM32F3) || defined(__RFduino__)
|
||||
#include "mbed/IPAddress.h"
|
||||
#else
|
||||
#include "IPAddress.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "utility/Enc28J60Network.h"
|
||||
#include "utility/uipopt.h"
|
||||
#include "Dhcp.h"
|
||||
#if UIP_UDP
|
||||
#include "UIPUdp.h"
|
||||
#endif
|
||||
#include "UIPClient.h"
|
||||
#include "UIPServer.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "utility/uip_timer.h"
|
||||
#include "utility/uip.h"
|
||||
}
|
||||
|
||||
#define UIPETHERNET_FREEPACKET 1
|
||||
#define UIPETHERNET_SENDPACKET 2
|
||||
#define UIPETHERNET_BUFFERREAD 4
|
||||
|
||||
#define uip_ip_addr(addr, ip) do { \
|
||||
((u16_t *)(addr))[0] = HTONS(((ip[0]) << 8) | (ip[1])); \
|
||||
((u16_t *)(addr))[1] = HTONS(((ip[2]) << 8) | (ip[3])); \
|
||||
} while(0)
|
||||
|
||||
#define ip_addr_uip(a) IPAddress(a[0] & 0xFF, a[0] >> 8 , a[1] & 0xFF, a[1] >> 8) //TODO this is not IPV6 capable
|
||||
|
||||
#define uip_seteth_addr(eaddr) do {uip_ethaddr.addr[0] = eaddr[0]; \
|
||||
uip_ethaddr.addr[1] = eaddr[1];\
|
||||
uip_ethaddr.addr[2] = eaddr[2];\
|
||||
uip_ethaddr.addr[3] = eaddr[3];\
|
||||
uip_ethaddr.addr[4] = eaddr[4];\
|
||||
uip_ethaddr.addr[5] = eaddr[5];} while(0)
|
||||
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
enum EthernetLinkStatus {
|
||||
Unknown,
|
||||
LinkON,
|
||||
LinkOFF
|
||||
};
|
||||
|
||||
class UIPEthernetClass
|
||||
{
|
||||
public:
|
||||
UIPEthernetClass();
|
||||
|
||||
void init(const uint8_t pin);
|
||||
|
||||
int begin(const uint8_t* mac);
|
||||
void begin(const uint8_t* mac, IPAddress ip);
|
||||
void begin(const uint8_t* mac, IPAddress ip, IPAddress dns);
|
||||
void begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway);
|
||||
void begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
|
||||
|
||||
// maintain() must be called at regular intervals to process the incoming serial
|
||||
// data and issue IP events to the sketch. It does not return until all IP
|
||||
// events have been processed. Renews dhcp-lease if required.
|
||||
int maintain();
|
||||
|
||||
EthernetLinkStatus linkStatus();
|
||||
|
||||
// KH add to have similar function to Ethernet lib
|
||||
// Certainly we can use void macAddress(uint8_t mac[]) to read from W5x00.
|
||||
void MACAddress(uint8_t *mac_address)
|
||||
{
|
||||
memcpy(mac_address, _mac_address, sizeof(_mac_address));
|
||||
}
|
||||
//////
|
||||
|
||||
IPAddress localIP();
|
||||
IPAddress subnetMask();
|
||||
IPAddress gatewayIP();
|
||||
IPAddress dnsServerIP();
|
||||
|
||||
private:
|
||||
|
||||
// KH add to work with new func void MACAddress(uint8_t *mac_address); and SinricPro v2.5.1+
|
||||
uint8_t _mac_address[6] ={0,};
|
||||
//////
|
||||
|
||||
static memhandle in_packet;
|
||||
static memhandle uip_packet;
|
||||
static uint8_t uip_hdrlen;
|
||||
static uint8_t packetstate;
|
||||
|
||||
static IPAddress _dnsServerAddress;
|
||||
#if UIP_UDP
|
||||
static DhcpClass* _dhcp;
|
||||
#endif
|
||||
static unsigned long periodic_timer;
|
||||
|
||||
static void netInit(const uint8_t* mac);
|
||||
static void configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
|
||||
|
||||
static void tick();
|
||||
|
||||
static bool network_send();
|
||||
|
||||
friend class UIPServer;
|
||||
|
||||
friend class UIPClient;
|
||||
|
||||
friend class UIPUDP;
|
||||
|
||||
static uint16_t chksum(uint16_t sum, const uint8_t* data, uint16_t len);
|
||||
static uint16_t ipchksum(void);
|
||||
#if UIP_UDP
|
||||
static uint16_t upper_layer_chksum(uint8_t proto);
|
||||
#endif
|
||||
friend uint16_t uip_ipchksum(void);
|
||||
friend uint16_t uip_tcpchksum(void);
|
||||
friend uint16_t uip_udpchksum(void);
|
||||
|
||||
friend void uipclient_appcall(void);
|
||||
friend void uipudp_appcall(void);
|
||||
|
||||
#if UIP_CONF_IPV6
|
||||
uint16_t uip_icmp6chksum(void);
|
||||
#endif /* UIP_CONF_IPV6 */
|
||||
};
|
||||
|
||||
extern UIPEthernetClass UIPEthernet;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,331 @@
|
||||
/*
|
||||
Enc28J60NetworkClass.h
|
||||
UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface.
|
||||
|
||||
Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
|
||||
All rights reserved.
|
||||
|
||||
inspired by enc28j60.c file from the AVRlib library by Pascal Stang.
|
||||
For AVRlib See http://www.procyonengineering.com/
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef Enc28J60Network_H_
|
||||
#define Enc28J60Network_H_
|
||||
|
||||
#if defined(ESP32)
|
||||
//pin SS already defined in ESP32 as pin 5, don't use this as conflict with SPIFFS, EEPROM, etc.
|
||||
// Use in GPIO13
|
||||
#warning ENC28J60Network.h => use ESP32, change ENC28J60_CONTROL_CS/SS_PIN_DEFAULT to GPIO13, MOSI(23), MISO(19), SCK(18)
|
||||
#define ENC28J60_CONTROL_CS 13
|
||||
#endif
|
||||
|
||||
// KH, For nRF52
|
||||
#if ( defined(NRF52840_FEATHER) || defined(NRF52832_FEATHER) || defined(NRF52_SERIES) || defined(ARDUINO_NRF52_ADAFRUIT) || \
|
||||
defined(NRF52840_FEATHER_SENSE) || defined(NRF52840_ITSYBITSY) || defined(NRF52840_CIRCUITPLAY) || defined(NRF52840_CLUE) || \
|
||||
defined(NRF52840_METRO) || defined(NRF52840_PCA10056) || defined(PARTICLE_XENON) || defined(NINA_B302_ublox) || defined(NINA_B112_ublox) )
|
||||
#include <SPI.h>
|
||||
#define ENC28J60_USE_SPILIB 1
|
||||
|
||||
#ifndef USE_THIS_SS_PIN
|
||||
// default to pin 10
|
||||
#define ENC28J60_CONTROL_CS 10
|
||||
#else
|
||||
#warning Using USE_THIS_SS_PIN in Enc28J60Network.h for nRF52
|
||||
#define ENC28J60_CONTROL_CS USE_THIS_SS_PIN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// KH, For SAMD21/SAMD51
|
||||
#if ( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
|
||||
|| defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
|
||||
|| defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(__SAMD21G18A__) \
|
||||
|| defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD21E18A__) || defined(__SAMD51__) || defined(__SAMD51J20A__) || defined(__SAMD51J19A__) \
|
||||
|| defined(__SAMD51G19A__) || defined(__SAMD51P19A__) || defined(__SAMD21G18A__) )
|
||||
#include <SPI.h>
|
||||
#define ENC28J60_USE_SPILIB 1
|
||||
|
||||
#ifndef USE_THIS_SS_PIN
|
||||
// default to pin 10
|
||||
#define ENC28J60_CONTROL_CS 10
|
||||
#else
|
||||
#warning Using USE_THIS_SS_PIN in Enc28J60Network.h for SAMD
|
||||
#define ENC28J60_CONTROL_CS USE_THIS_SS_PIN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "mempool.h"
|
||||
#if defined(__MBED__)
|
||||
#include <mbed.h>
|
||||
//UIPEthernet(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS);
|
||||
#if defined(TARGET_LPC1768)
|
||||
#define SPI_MOSI p11
|
||||
#define SPI_MISO p12
|
||||
#define SPI_SCK p13
|
||||
#define SPI_CS p8
|
||||
#elif defined(TARGET_LPC1114)
|
||||
#define SPI_MOSI dp2
|
||||
#define SPI_MISO dp1
|
||||
#define SPI_SCK dp6
|
||||
#define SPI_CS dp25
|
||||
#elif defined(TARGET_LPC11U68)
|
||||
#define SPI_MOSI P0_9
|
||||
#define SPI_MISO P0_8
|
||||
#define SPI_SCK P1_29
|
||||
#define SPI_CS P0_2
|
||||
#elif defined(TARGET_NUCLEO_F103RB) || defined(TARGET_NUCLEO_L152RE) || defined(TARGET_NUCLEO_F030R8) \
|
||||
|| defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F302R8) || defined(TARGET_NUCLEO_L053R8) \
|
||||
|| defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F334R8) || defined(TARGET_NUCLEO_F072RB) \
|
||||
|| defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F070RB)
|
||||
#define SPI_MOSI D4
|
||||
#define SPI_MISO D5
|
||||
#define SPI_SCK D3
|
||||
#define SPI_CS D2
|
||||
#endif
|
||||
#define ENC28J60_CONTROL_CS SPI_CS
|
||||
#endif
|
||||
|
||||
#if defined(STM32F3) || defined(STM32F2) //This is workaround for stm32duino STM32F2, and adafruit wiced feather STM32F2
|
||||
#define BOARD_SPI1_NSS_PIN PA4
|
||||
#define BOARD_SPI1_SCK_PIN PA5
|
||||
#define BOARD_SPI1_MISO_PIN PA6
|
||||
#define BOARD_SPI1_MOSI_PIN PA7
|
||||
#endif //This is workaround for stm32duino STM32F3, and adafruit wiced feather STM32F2
|
||||
|
||||
#if defined(BOARD_discovery_f4)
|
||||
#define __STM32F4__
|
||||
#endif
|
||||
#if defined(__MK20DX128__) || defined(__MKL26Z64__)
|
||||
#include <SPIFIFO.h>
|
||||
#endif
|
||||
|
||||
#if !defined(ENC28J60_CONTROL_CS)
|
||||
#if defined(__AVR__) || defined(ESP8266) || defined(__RFduino__)
|
||||
// Arduino Uno (__AVR__) SS defined to pin 10
|
||||
// Arduino Leonardo (ARDUINO_AVR_LEONARDO) SS defined to LED_BUILTIN_RX (17)
|
||||
// Arduino Mega(__AVR_ATmega2560__) SS defined to pin 53
|
||||
// ESP8266 (ESP8266) SS defined to pin 15
|
||||
#if defined(ARDUINO_AVR_LEONARDO) || defined(ARDUINO_AVR_MICRO)
|
||||
#define ENC28J60_CONTROL_CS PIN_A10
|
||||
#warning "Using LEONARDO borad PIN_A10 for ENC28J60_CONTROL_CS. Use UIPEthernet::init(uint8_t) to change it."
|
||||
#else
|
||||
#define ENC28J60_CONTROL_CS SS
|
||||
#endif
|
||||
#elif defined(ARDUINO_ARCH_AMEBA) //Defined SS to pin 10
|
||||
#define ENC28J60_CONTROL_CS SS //PC_0 A5 10
|
||||
#elif defined(ARDUINO_ARCH_SAM)
|
||||
// Arduino Due (ARDUINO_ARCH_SAM) BOARD_SPI_DEFAULT_SS (SS3) defined to pin 78
|
||||
//#define ENC28J60_CONTROL_CS BOARD_SPI_DEFAULT_SS
|
||||
#define ENC28J60_CONTROL_CS BOARD_SPI_SS0
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
#define ENC28J60_CONTROL_CS SS
|
||||
#elif defined(__ARDUINO_ARC__) //Intel ARC32 Genuino 101
|
||||
#define ENC28J60_CONTROL_CS SS
|
||||
#elif defined(__RFduino__) //RFduino
|
||||
#define ENC28J60_CONTROL_CS SS
|
||||
#elif defined(ARDUINO_ARCH_STM32) // STM32duino core
|
||||
#define ENC28J60_CONTROL_CS SS
|
||||
#elif defined(ARDUINO_ARCH_ESP32) // arduino-esp32
|
||||
#define ENC28J60_CONTROL_CS SS
|
||||
#elif defined(STM32_MCU_SERIES) || defined(__STM32F1__) || defined(__STM32F3__) || defined(STM32F3) || defined(__STM32F4__) || defined(STM32F2)
|
||||
#if defined(BOARD_SPI1_NSS_PIN)
|
||||
#define ENC28J60_CONTROL_CS BOARD_SPI1_NSS_PIN
|
||||
#elif defined(ARDUINO_STM32F4_NETDUINO2PLUS)
|
||||
#define ENC28J60_CONTROL_CS PC8
|
||||
#else
|
||||
#define ENC28J60_CONTROL_CS SPI.nssPin()
|
||||
//#define ENC28J60_CONTROL_CS PA4
|
||||
#endif
|
||||
#elif defined(__MK20DX128__) || defined(__MKL26Z64__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__)
|
||||
#define ENC28J60_CONTROL_CS PIN_SPI_SS
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(ENC28J60_CONTROL_CS)
|
||||
#warning "Default ENC28J60_CONTROL_CS could not be defined! Use UIPEthernet::init(uint8_t) to set it."
|
||||
#define ENC28J60_CONTROL_CS 0
|
||||
#endif
|
||||
|
||||
extern uint8_t ENC28J60ControlCS;
|
||||
|
||||
#if !defined(SPI_MOSI)
|
||||
#if defined(__AVR__) || defined(ESP8266) || defined(__RFduino__)
|
||||
#define SPI_MOSI MOSI
|
||||
#elif defined(ARDUINO_ARCH_AMEBA)
|
||||
#define SPI_MOSI 11 //PC_2
|
||||
#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
|
||||
#define SPI_MOSI PIN_SPI_MOSI
|
||||
#elif defined(__ARDUINO_ARC__) //Intel ARC32 Genuino 101
|
||||
#define SPI_MOSI MOSI
|
||||
#elif defined(__RFduino__) //RFduino
|
||||
#define SPI_MOSI MOSI
|
||||
#elif defined(ARDUINO_ARCH_STM32) // STM32duino core
|
||||
#define SPI_MOSI MOSI
|
||||
#elif defined(ARDUINO_ARCH_ESP32) // arduino-esp32
|
||||
#define SPI_MOSI MOSI
|
||||
#elif defined(STM32_MCU_SERIES) || defined(__STM32F1__) || defined(__STM32F3__) || defined(STM32F3) || defined(__STM32F4__) || defined(STM32F2)
|
||||
#if defined(BOARD_SPI1_MOSI_PIN)
|
||||
#define SPI_MOSI BOARD_SPI1_MOSI_PIN
|
||||
#else
|
||||
#define SPI_MOSI SPI.mosiPin()
|
||||
#endif
|
||||
#elif defined(__MK20DX128__) || defined(__MKL26Z64__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__)
|
||||
#define SPI_MOSI PIN_SPI_MOSI
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SPI_MOSI)
|
||||
//#error "Not defined SPI_MOSI!"
|
||||
#define SPI_MOSI MOSI
|
||||
#endif
|
||||
|
||||
#if !defined(SPI_MISO)
|
||||
#if defined(__AVR__) || defined(ESP8266) || defined(__RFduino__)
|
||||
#define SPI_MISO MISO
|
||||
#elif defined(ARDUINO_ARCH_AMEBA)
|
||||
#define SPI_MISO 12 //PC_3
|
||||
#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
|
||||
#define SPI_MISO PIN_SPI_MISO
|
||||
#elif defined(__ARDUINO_ARC__) //Intel ARC32 Genuino 101
|
||||
#define SPI_MISO MISO
|
||||
#elif defined(__RFduino__) //RFduino
|
||||
#define SPI_MISO MISO
|
||||
#elif defined(ARDUINO_ARCH_STM32) // STM32duino core
|
||||
#define SPI_MISO MISO
|
||||
#elif defined(ARDUINO_ARCH_ESP32) // arduino-esp32
|
||||
#define SPI_MISO MISO
|
||||
#elif defined(STM32_MCU_SERIES) || defined(__STM32F1__) || defined(__STM32F3__) || defined(STM32F3) || defined(__STM32F4__) || defined(STM32F2)
|
||||
#if defined(BOARD_SPI1_MISO_PIN)
|
||||
#define SPI_MISO BOARD_SPI1_MISO_PIN
|
||||
#else
|
||||
#define SPI_MISO SPI.misoPin()
|
||||
#endif
|
||||
#elif defined(__MK20DX128__) || defined(__MKL26Z64__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__)
|
||||
#define SPI_MISO PIN_SPI_MISO
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SPI_MISO)
|
||||
//#error "Not defined SPI_MISO!"
|
||||
#define SPI_MISO MISO
|
||||
#endif
|
||||
#if !defined(SPI_SCK)
|
||||
#if defined(__AVR__) || defined(ESP8266) || defined(__RFduino__)
|
||||
#define SPI_SCK SCK
|
||||
#elif defined(ARDUINO_ARCH_AMEBA)
|
||||
#define SPI_SCK 13 //PC_1 A4
|
||||
#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
|
||||
#define SPI_SCK PIN_SPI_SCK
|
||||
#elif defined(__ARDUINO_ARC__) //Intel ARC32 Genuino 101
|
||||
#define SPI_SCK SCK
|
||||
#elif defined(__RFduino__) //RFduino
|
||||
#define SPI_SCK SCK
|
||||
#elif defined(ARDUINO_ARCH_STM32) // STM32duino core
|
||||
#define SPI_SCK SCK
|
||||
#elif defined(ARDUINO_ARCH_ESP32) // arduino-esp32
|
||||
#define SPI_SCK SCK
|
||||
#elif defined(STM32_MCU_SERIES) || defined(__STM32F1__) || defined(__STM32F3__) || defined(STM32F3) || defined(__STM32F4__) || defined(STM32F2)
|
||||
#if defined(BOARD_SPI1_SCK_PIN)
|
||||
#define SPI_SCK BOARD_SPI1_SCK_PIN
|
||||
#else
|
||||
#define SPI_SCK SPI.sckPin()
|
||||
#endif
|
||||
#elif defined(__MK20DX128__) || defined(__MKL26Z64__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__)
|
||||
#define SPI_SCK PIN_SPI_SCK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(SPI_SCK)
|
||||
// For nRF52
|
||||
//#error "Not defined SPI_SCK!"
|
||||
#define SPI_SCK SCK
|
||||
#endif
|
||||
|
||||
#if defined(__MBED__) || defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) || defined(__ARDUINO_ARC__) || defined(__STM32F1__) || defined(__STM32F3__) || defined(STM32F3) || defined(__STM32F4__) || defined(STM32F2) || defined(ESP8266) || defined(ARDUINO_ARCH_AMEBA) || defined(__MK20DX128__) || defined(__MKL26Z64__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__) || defined(__RFduino__) || defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
|
||||
#if defined(ARDUINO) && defined(STM32F3)
|
||||
#include "HardwareSPI.h"
|
||||
#else
|
||||
#include <SPI.h>
|
||||
#endif
|
||||
#define ENC28J60_USE_SPILIB 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define UIP_RECEIVEBUFFERHANDLE 0xff
|
||||
|
||||
/*
|
||||
* Empfangen von ip-header, arp etc...
|
||||
* wenn tcp/udp -> tcp/udp-callback -> assign new packet to connection
|
||||
*/
|
||||
|
||||
#define TX_COLLISION_RETRY_COUNT 10
|
||||
|
||||
class Enc28J60Network : public MemoryPool
|
||||
{
|
||||
|
||||
private:
|
||||
static uint16_t nextPacketPtr;
|
||||
static uint8_t bank;
|
||||
static uint8_t erevid;
|
||||
|
||||
static struct memblock receivePkt;
|
||||
|
||||
static bool broadcast_enabled; //!< True if broadcasts enabled (used to allow temporary disable of broadcast for DHCP or other internal functions)
|
||||
|
||||
static uint8_t readOp(uint8_t op, uint8_t address);
|
||||
static void writeOp(uint8_t op, uint8_t address, uint8_t data);
|
||||
static uint16_t setReadPtr(memhandle handle, memaddress position, uint16_t len);
|
||||
static void setERXRDPT(void);
|
||||
static void readBuffer(uint16_t len, uint8_t* data);
|
||||
static void writeBuffer(uint16_t len, uint8_t* data);
|
||||
static uint8_t readByte(uint16_t addr);
|
||||
static void writeByte(uint16_t addr, uint8_t data);
|
||||
static void setBank(uint8_t address);
|
||||
static uint8_t readReg(uint8_t address);
|
||||
static void writeReg(uint8_t address, uint8_t data);
|
||||
static void writeRegPair(uint8_t address, uint16_t data);
|
||||
static void phyWrite(uint8_t address, uint16_t data);
|
||||
static uint16_t phyRead(uint8_t address);
|
||||
static void clkout(uint8_t clk);
|
||||
|
||||
static void enableBroadcast (bool temporary);
|
||||
static void disableBroadcast (bool temporary);
|
||||
static void enableMulticast (void);
|
||||
static void disableMulticast (void);
|
||||
|
||||
static uint8_t readRegByte (uint8_t address);
|
||||
static void writeRegByte (uint8_t address, uint8_t data);
|
||||
|
||||
friend void enc28J60_mempool_block_move_callback(memaddress,memaddress,memaddress);
|
||||
|
||||
public:
|
||||
|
||||
void powerOn(void);
|
||||
void powerOff(void);
|
||||
static uint8_t geterevid(void);
|
||||
uint16_t PhyStatus(void);
|
||||
static bool linkStatus(void);
|
||||
|
||||
static void init(uint8_t* macaddr);
|
||||
static memhandle receivePacket(void);
|
||||
static void freePacket(void);
|
||||
static memaddress blockSize(memhandle handle);
|
||||
static void sendPacket(memhandle handle);
|
||||
static uint16_t readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len);
|
||||
static uint16_t writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len);
|
||||
static void copyPacket(memhandle dest, memaddress dest_pos, memhandle src, memaddress src_pos, uint16_t len);
|
||||
static uint16_t chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len);
|
||||
};
|
||||
|
||||
extern Enc28J60Network Enc28J60;
|
||||
#endif /* Enc28J60NetworkClass_H_ */
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Server.h - Base class that provides Server
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef server_h
|
||||
#define server_h
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
class Server: public Print
|
||||
{
|
||||
public:
|
||||
// KH, change to fix compiler error for EthernetWebServer
|
||||
// error: cannot declare field 'EthernetWebServer::_server' to be of abstract type 'EthernetServer'
|
||||
// virtual void begin(uint16_t port=0) =0;
|
||||
//virtual void begin() = 0;
|
||||
void begin() {};
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,129 @@
|
||||
/*
|
||||
Stream.h - base class for character-based streams.
|
||||
Copyright (c) 2010 David A. Mellis. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
parsing functions based on TextFinder library by Michael Margolis
|
||||
*/
|
||||
|
||||
#ifndef Stream_h
|
||||
#define Stream_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "Print.h"
|
||||
|
||||
// compatability macros for testing
|
||||
/*
|
||||
#define getInt() parseInt()
|
||||
#define getInt(ignore) parseInt(ignore)
|
||||
#define getFloat() parseFloat()
|
||||
#define getFloat(ignore) parseFloat(ignore)
|
||||
#define getString( pre_string, post_string, buffer, length)
|
||||
readBytesBetween( pre_string, terminator, buffer, length)
|
||||
*/
|
||||
|
||||
// This enumeration provides the lookahead options for parseInt(), parseFloat()
|
||||
// The rules set out here are used until either the first valid character is found
|
||||
// or a time out occurs due to lack of input.
|
||||
enum LookaheadMode{
|
||||
SKIP_ALL, // All invalid characters are ignored.
|
||||
SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
|
||||
SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
|
||||
};
|
||||
|
||||
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
|
||||
|
||||
class Stream : public Print
|
||||
{
|
||||
protected:
|
||||
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
|
||||
unsigned long _startMillis = 0; // used for timeout measurement
|
||||
int timedRead(); // read stream with timeout
|
||||
int timedPeek(); // peek stream with timeout
|
||||
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
|
||||
|
||||
public:
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
|
||||
Stream() {_timeout=1000;}
|
||||
|
||||
// parsing methods
|
||||
|
||||
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
|
||||
unsigned long getTimeout(void) { return _timeout; }
|
||||
|
||||
bool find(char *target); // reads data from the stream until the target string is found
|
||||
bool find(uint8_t *target) { return find ((char *)target); }
|
||||
// returns true if target string is found, false if timed out (see setTimeout)
|
||||
|
||||
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
|
||||
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
|
||||
// returns true if target string is found, false if timed out
|
||||
|
||||
bool find(char target) { return find (&target, 1); }
|
||||
|
||||
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
|
||||
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
|
||||
|
||||
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
|
||||
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
|
||||
|
||||
long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
|
||||
// returns the first valid (long) integer value from the current position.
|
||||
// lookahead determines how parseInt looks ahead in the stream.
|
||||
// See LookaheadMode enumeration at the top of the file.
|
||||
// Lookahead is terminated by the first character that is not a valid part of an integer.
|
||||
// Once parsing commences, 'ignore' will be skipped in the stream.
|
||||
|
||||
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
|
||||
// float version of parseInt
|
||||
|
||||
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
|
||||
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
|
||||
// terminates if length characters have been read or timeout (see setTimeout)
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
|
||||
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
|
||||
// terminates if length characters have been read, timeout, or if the terminator character detected
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
// Arduino String functions to be added here
|
||||
String readString();
|
||||
String readStringUntil(char terminator);
|
||||
|
||||
protected:
|
||||
long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); }
|
||||
float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); }
|
||||
// These overload exists for compatibility with any class that has derived
|
||||
// Stream and used parseFloat/Int with a custom ignore character. To keep
|
||||
// the public API simple, these overload remains protected.
|
||||
|
||||
struct MultiTarget {
|
||||
const char *str; // string you're searching for
|
||||
size_t len; // length of string you're searching for
|
||||
size_t index; // index used by the search routine.
|
||||
};
|
||||
|
||||
// This allows you to search for an arbitrary number of strings.
|
||||
// Returns index of the target that is found first or -1 if timeout occurs.
|
||||
int findMulti(struct MultiTarget *targets, int tCount);
|
||||
};
|
||||
|
||||
#undef NO_IGNORE_CHAR
|
||||
#endif
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
Stream.h - base class for character-based streams.
|
||||
Copyright (c) 2010 David A. Mellis. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
parsing functions based on TextFinder library by Michael Margolis
|
||||
*/
|
||||
|
||||
#ifndef Stream_h
|
||||
#define Stream_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "Print.h"
|
||||
|
||||
// compatability macros for testing
|
||||
/*
|
||||
#define getInt() parseInt()
|
||||
#define getInt(ignore) parseInt(ignore)
|
||||
#define getFloat() parseFloat()
|
||||
#define getFloat(ignore) parseFloat(ignore)
|
||||
#define getString( pre_string, post_string, buffer, length)
|
||||
readBytesBetween( pre_string, terminator, buffer, length)
|
||||
*/
|
||||
|
||||
// This enumeration provides the lookahead options for parseInt(), parseFloat()
|
||||
// The rules set out here are used until either the first valid character is found
|
||||
// or a time out occurs due to lack of input.
|
||||
enum LookaheadMode{
|
||||
SKIP_ALL, // All invalid characters are ignored.
|
||||
SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
|
||||
SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
|
||||
};
|
||||
|
||||
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
|
||||
|
||||
class Stream : public Print
|
||||
{
|
||||
protected:
|
||||
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
|
||||
unsigned long _startMillis = 0; // used for timeout measurement
|
||||
int timedRead(); // read stream with timeout
|
||||
int timedPeek(); // peek stream with timeout
|
||||
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
|
||||
|
||||
public:
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
|
||||
Stream() {_timeout=1000;}
|
||||
|
||||
// parsing methods
|
||||
|
||||
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
|
||||
unsigned long getTimeout(void) { return _timeout; }
|
||||
|
||||
bool find(char *target); // reads data from the stream until the target string is found
|
||||
bool find(uint8_t *target) { return find ((char *)target); }
|
||||
// returns true if target string is found, false if timed out (see setTimeout)
|
||||
|
||||
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
|
||||
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
|
||||
// returns true if target string is found, false if timed out
|
||||
|
||||
bool find(char target) { return find (&target, 1); }
|
||||
|
||||
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
|
||||
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
|
||||
|
||||
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
|
||||
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
|
||||
|
||||
long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
|
||||
// returns the first valid (long) integer value from the current position.
|
||||
// lookahead determines how parseInt looks ahead in the stream.
|
||||
// See LookaheadMode enumeration at the top of the file.
|
||||
// Lookahead is terminated by the first character that is not a valid part of an integer.
|
||||
// Once parsing commences, 'ignore' will be skipped in the stream.
|
||||
|
||||
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
|
||||
// float version of parseInt
|
||||
|
||||
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
|
||||
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
|
||||
// terminates if length characters have been read or timeout (see setTimeout)
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
|
||||
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
|
||||
// terminates if length characters have been read, timeout, or if the terminator character detected
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
// Arduino String functions to be added here
|
||||
String readString();
|
||||
String readStringUntil(char terminator);
|
||||
|
||||
protected:
|
||||
long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); }
|
||||
float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); }
|
||||
// These overload exists for compatibility with any class that has derived
|
||||
// Stream and used parseFloat/Int with a custom ignore character. To keep
|
||||
// the public API simple, these overload remains protected.
|
||||
|
||||
struct MultiTarget {
|
||||
const char *str; // string you're searching for
|
||||
size_t len; // length of string you're searching for
|
||||
size_t index; // index used by the search routine.
|
||||
};
|
||||
|
||||
// This allows you to search for an arbitrary number of strings.
|
||||
// Returns index of the target that is found first or -1 if timeout occurs.
|
||||
int findMulti(struct MultiTarget *targets, int tCount);
|
||||
};
|
||||
|
||||
#undef NO_IGNORE_CHAR
|
||||
#endif
|
@ -0,0 +1,513 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_hal_conf_default.h
|
||||
* @brief HAL default configuration file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F4xx_HAL_CONF_DEFAULT_H
|
||||
#define __STM32F4xx_HAL_CONF_DEFAULT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief Include the default list of modules to be used in the HAL driver
|
||||
* and manage module deactivation
|
||||
*/
|
||||
#include "stm32yyxx_hal_conf.h"
|
||||
#if 0
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
#define HAL_MODULE_ENABLED
|
||||
#define HAL_ADC_MODULE_ENABLED
|
||||
#define HAL_CAN_MODULE_ENABLED
|
||||
/*#define HAL_CAN_LEGACY_MODULE_ENABLED*/
|
||||
#define HAL_CRC_MODULE_ENABLED
|
||||
#define HAL_CEC_MODULE_ENABLED
|
||||
#define HAL_CRYP_MODULE_ENABLED
|
||||
#define HAL_DAC_MODULE_ENABLED
|
||||
#define HAL_DCMI_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_DMA2D_MODULE_ENABLED
|
||||
#define HAL_ETH_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_NAND_MODULE_ENABLED
|
||||
#define HAL_NOR_MODULE_ENABLED
|
||||
#define HAL_PCCARD_MODULE_ENABLED
|
||||
#define HAL_SRAM_MODULE_ENABLED
|
||||
#define HAL_SDRAM_MODULE_ENABLED
|
||||
#define HAL_HASH_MODULE_ENABLED
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
#define HAL_SMBUS_MODULE_ENABLED
|
||||
#define HAL_I2S_MODULE_ENABLED
|
||||
#define HAL_IWDG_MODULE_ENABLED
|
||||
#define HAL_LTDC_MODULE_ENABLED
|
||||
#define HAL_DSI_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_QSPI_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
#define HAL_RNG_MODULE_ENABLED
|
||||
#define HAL_RTC_MODULE_ENABLED
|
||||
#define HAL_SAI_MODULE_ENABLED
|
||||
#define HAL_SD_MODULE_ENABLED
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
#define HAL_USART_MODULE_ENABLED
|
||||
#define HAL_IRDA_MODULE_ENABLED
|
||||
#define HAL_SMARTCARD_MODULE_ENABLED
|
||||
#define HAL_WWDG_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
#define HAL_PCD_MODULE_ENABLED
|
||||
#define HAL_HCD_MODULE_ENABLED
|
||||
#define HAL_FMPI2C_MODULE_ENABLED
|
||||
#define HAL_SPDIFRX_MODULE_ENABLED
|
||||
#define HAL_DFSDM_MODULE_ENABLED
|
||||
#define HAL_LPTIM_MODULE_ENABLED
|
||||
#define HAL_MMC_MODULE_ENABLED
|
||||
#endif
|
||||
|
||||
/* ########################## HSE/HSI Values adaptation ##################### */
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSE is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI) value.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSI is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE 32000U /*!< LSI Typical Value in Hz */
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature. */
|
||||
/**
|
||||
* @brief External Low Speed oscillator (LSE) value.
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief External clock source for I2S peripheral
|
||||
* This value is used by the I2S HAL module to compute the I2S clock source
|
||||
* frequency, this source is inserted directly through I2S_CKIN pad.
|
||||
*/
|
||||
#if !defined (EXTERNAL_CLOCK_VALUE)
|
||||
#define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the External oscillator in Hz*/
|
||||
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
#if !defined (VDD_VALUE)
|
||||
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
|
||||
#endif
|
||||
#if !defined (TICK_INT_PRIORITY)
|
||||
#define TICK_INT_PRIORITY 0x00U /*!< tick interrupt priority */
|
||||
#endif
|
||||
#if !defined (USE_RTOS)
|
||||
#define USE_RTOS 0U
|
||||
#endif
|
||||
#if !defined (PREFETCH_ENABLE)
|
||||
#define PREFETCH_ENABLE 1U
|
||||
#endif
|
||||
#if !defined (INSTRUCTION_CACHE_ENABLE)
|
||||
#define INSTRUCTION_CACHE_ENABLE 1U
|
||||
#endif
|
||||
#if !defined (DATA_CACHE_ENABLE)
|
||||
#define DATA_CACHE_ENABLE 1U
|
||||
#endif
|
||||
|
||||
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
|
||||
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
|
||||
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
|
||||
#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */
|
||||
#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */
|
||||
#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */
|
||||
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
|
||||
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||
#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */
|
||||
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
|
||||
#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */
|
||||
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||
#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */
|
||||
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */
|
||||
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
|
||||
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
|
||||
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
|
||||
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
|
||||
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1U */
|
||||
|
||||
/* ################## Ethernet peripheral configuration ##################### */
|
||||
|
||||
/* Section 1 : Ethernet peripheral configuration */
|
||||
|
||||
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||
#define MAC_ADDR0 2U
|
||||
#define MAC_ADDR1 0U
|
||||
#define MAC_ADDR2 0U
|
||||
#define MAC_ADDR3 0U
|
||||
#define MAC_ADDR4 0U
|
||||
#define MAC_ADDR5 0U
|
||||
|
||||
/* Definition of the Ethernet driver buffers size and count */
|
||||
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||
#define ETH_RXBUFNB (5U) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||
#define ETH_TXBUFNB (5U) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||
|
||||
/* Section 2: PHY configuration section */
|
||||
/* LAN8742A PHY Address*/
|
||||
////////////////////////////////
|
||||
//#define LAN8742A_PHY_ADDRESS 0x00U
|
||||
/* Section 2: PHY configuration section */
|
||||
#if !defined (LAN8742A_PHY_ADDRESS)
|
||||
/* LAN8742A PHY Address*/
|
||||
#define LAN8742A_PHY_ADDRESS 0x00U
|
||||
#endif
|
||||
////////////////////////////////
|
||||
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||
#define PHY_RESET_DELAY 0x000000FFU
|
||||
/* PHY Configuration delay */
|
||||
#define PHY_CONFIG_DELAY 0x00000FFFU
|
||||
|
||||
#define PHY_READ_TO 0x0000FFFFU
|
||||
#define PHY_WRITE_TO 0x0000FFFFU
|
||||
|
||||
/* Section 3: Common PHY Registers */
|
||||
|
||||
#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */
|
||||
#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */
|
||||
|
||||
#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
|
||||
#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
|
||||
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
|
||||
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
|
||||
#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
|
||||
#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
|
||||
|
||||
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
|
||||
#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
|
||||
#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
|
||||
|
||||
/* Section 4: Extended PHY Registers */
|
||||
|
||||
#define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */
|
||||
|
||||
#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */
|
||||
#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */
|
||||
|
||||
|
||||
#define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */
|
||||
#define PHY_IMR ((uint16_t)0x1E) /*!< PHY Interrupt Mask register Offset */
|
||||
#define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */
|
||||
|
||||
/* ################## SPI peripheral configuration ########################## */
|
||||
|
||||
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||
* Activated: CRC code is present inside driver
|
||||
* Deactivated: CRC code cleaned from driver
|
||||
*/
|
||||
#if !defined (USE_SPI_CRC)
|
||||
#define USE_SPI_CRC 0U
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_can.h"
|
||||
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_can_legacy.h"
|
||||
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_cryp.h"
|
||||
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA2D_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dma2d.h"
|
||||
#endif /* HAL_DMA2D_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DCMI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dcmi.h"
|
||||
#endif /* HAL_DCMI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ETH_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_eth.h"
|
||||
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sram.h"
|
||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NOR_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_nor.h"
|
||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NAND_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_nand.h"
|
||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCCARD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_pccard.h"
|
||||
#endif /* HAL_PCCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SDRAM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sdram.h"
|
||||
#endif /* HAL_SDRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HASH_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_hash.h"
|
||||
#endif /* HAL_HASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMBUS_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_smbus.h"
|
||||
#endif /* HAL_SMBUS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LTDC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_ltdc.h"
|
||||
#endif /* HAL_LTDC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RNG_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_rng.h"
|
||||
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SAI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sai.h"
|
||||
#endif /* HAL_SAI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sd.h"
|
||||
#endif /* HAL_SD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_hcd.h"
|
||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DSI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dsi.h"
|
||||
#endif /* HAL_DSI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_QSPI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_qspi.h"
|
||||
#endif /* HAL_QSPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CEC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_cec.h"
|
||||
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FMPI2C_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_fmpi2c.h"
|
||||
#endif /* HAL_FMPI2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPDIFRX_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_spdifrx.h"
|
||||
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DFSDM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dfsdm.h"
|
||||
#endif /* HAL_DFSDM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_lptim.h"
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MMC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_mmc.h"
|
||||
#endif /* HAL_MMC_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t *file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F4xx_HAL_CONF_DEFAULT_H */
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,511 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f7xx_hal_conf_default.h
|
||||
* @brief HAL default configuration file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F7xx_HAL_CONF_DEFAULT_H
|
||||
#define __STM32F7xx_HAL_CONF_DEFAULT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief Include the default list of modules to be used in the HAL driver
|
||||
* and manage module deactivation
|
||||
*/
|
||||
#include "stm32yyxx_hal_conf.h"
|
||||
#if 0
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
#define HAL_MODULE_ENABLED
|
||||
#define HAL_ADC_MODULE_ENABLED
|
||||
#define HAL_CAN_MODULE_ENABLED
|
||||
#define HAL_CAN_LEGACY_MODULE_ENABLED
|
||||
#define HAL_CEC_MODULE_ENABLED
|
||||
#define HAL_CRC_MODULE_ENABLED
|
||||
#define HAL_CRYP_MODULE_ENABLED
|
||||
#define HAL_DAC_MODULE_ENABLED
|
||||
#define HAL_DCMI_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_DMA2D_MODULE_ENABLED
|
||||
#define HAL_ETH_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_NAND_MODULE_ENABLED
|
||||
#define HAL_NOR_MODULE_ENABLED
|
||||
#define HAL_SRAM_MODULE_ENABLED
|
||||
#define HAL_SDRAM_MODULE_ENABLED
|
||||
#define HAL_HASH_MODULE_ENABLED
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
#define HAL_I2S_MODULE_ENABLED
|
||||
#define HAL_IWDG_MODULE_ENABLED
|
||||
#define HAL_LPTIM_MODULE_ENABLED
|
||||
#define HAL_LTDC_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_QSPI_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
#define HAL_RNG_MODULE_ENABLED
|
||||
#define HAL_RTC_MODULE_ENABLED
|
||||
#define HAL_SAI_MODULE_ENABLED
|
||||
#define HAL_SD_MODULE_ENABLED
|
||||
#define HAL_SPDIFRX_MODULE_ENABLED
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
#define HAL_USART_MODULE_ENABLED
|
||||
#define HAL_IRDA_MODULE_ENABLED
|
||||
#define HAL_SMARTCARD_MODULE_ENABLED
|
||||
#define HAL_WWDG_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
#define HAL_PCD_MODULE_ENABLED
|
||||
#define HAL_HCD_MODULE_ENABLED
|
||||
#define HAL_DFSDM_MODULE_ENABLED
|
||||
#define HAL_DSI_MODULE_ENABLED
|
||||
#define HAL_JPEG_MODULE_ENABLED
|
||||
#define HAL_MDIOS_MODULE_ENABLED
|
||||
#define HAL_SMBUS_MODULE_ENABLED
|
||||
#define HAL_MMC_MODULE_ENABLED
|
||||
#endif
|
||||
|
||||
/* ########################## HSE/HSI Values adaptation ##################### */
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSE is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI) value.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSI is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature. */
|
||||
/**
|
||||
* @brief External Low Speed oscillator (LSE) value.
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief External clock source for I2S peripheral
|
||||
* This value is used by the I2S HAL module to compute the I2S clock source
|
||||
* frequency, this source is inserted directly through I2S_CKIN pad.
|
||||
*/
|
||||
#if !defined (EXTERNAL_CLOCK_VALUE)
|
||||
#define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
#if !defined (VDD_VALUE)
|
||||
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
|
||||
#endif
|
||||
#if !defined (TICK_INT_PRIORITY)
|
||||
#define TICK_INT_PRIORITY 0x00U /*!< tick interrupt priority */
|
||||
#endif
|
||||
#if !defined (USE_RTOS)
|
||||
#define USE_RTOS 0U
|
||||
#endif
|
||||
#if !defined (PREFETCH_ENABLE)
|
||||
#define PREFETCH_ENABLE 1U /* To enable prefetch */
|
||||
#endif
|
||||
#if !defined (ART_ACCLERATOR_ENABLE)
|
||||
#define ART_ACCLERATOR_ENABLE 1U /* To enable ART Accelerator */
|
||||
#endif
|
||||
|
||||
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
|
||||
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
|
||||
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
|
||||
#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */
|
||||
#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */
|
||||
#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */
|
||||
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
|
||||
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||
#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */
|
||||
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
|
||||
#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */
|
||||
#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIOS register callback disabled */
|
||||
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */
|
||||
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
|
||||
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
|
||||
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
|
||||
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
|
||||
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1 */
|
||||
|
||||
/* ################## Ethernet peripheral configuration ##################### */
|
||||
|
||||
/* Section 1 : Ethernet peripheral configuration */
|
||||
|
||||
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||
#define MAC_ADDR0 2U
|
||||
#define MAC_ADDR1 0U
|
||||
#define MAC_ADDR2 0U
|
||||
#define MAC_ADDR3 0U
|
||||
#define MAC_ADDR4 0U
|
||||
#define MAC_ADDR5 0U
|
||||
|
||||
/* Definition of the Ethernet driver buffers size and count */
|
||||
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||
#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||
#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||
|
||||
/* Section 2: PHY configuration section */
|
||||
/* LAN8742A PHY Address*/
|
||||
////////////////////////////////
|
||||
//#define LAN8742A_PHY_ADDRESS 0x00U
|
||||
/* Section 2: PHY configuration section */
|
||||
#if !defined (LAN8742A_PHY_ADDRESS)
|
||||
/* LAN8742A PHY Address*/
|
||||
#define LAN8742A_PHY_ADDRESS 0x00U
|
||||
#endif
|
||||
////////////////////////////////
|
||||
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||
#define PHY_RESET_DELAY 0x00000FFFU
|
||||
/* PHY Configuration delay */
|
||||
#define PHY_CONFIG_DELAY 0x00000FFFU
|
||||
|
||||
#define PHY_READ_TO 0x0000FFFFU
|
||||
#define PHY_WRITE_TO 0x0000FFFFU
|
||||
|
||||
/* Section 3: Common PHY Registers */
|
||||
|
||||
#define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */
|
||||
#define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */
|
||||
|
||||
#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
|
||||
#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
|
||||
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
|
||||
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
|
||||
#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
|
||||
#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
|
||||
|
||||
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
|
||||
#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
|
||||
#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
|
||||
|
||||
/* Section 4: Extended PHY Registers */
|
||||
|
||||
#define PHY_SR ((uint16_t)0x1FU) /*!< PHY special control/ status register Offset */
|
||||
|
||||
#define PHY_SPEED_STATUS ((uint16_t)0x0004U) /*!< PHY Speed mask */
|
||||
#define PHY_DUPLEX_STATUS ((uint16_t)0x0010U) /*!< PHY Duplex mask */
|
||||
|
||||
|
||||
#define PHY_ISFR ((uint16_t)0x01DU) /*!< PHY Interrupt Source Flag register Offset */
|
||||
#define PHY_IMR ((uint16_t)0x001E) /*!< PHY Interrupt Mask register Offset */
|
||||
#define PHY_ISFR_INT4 ((uint16_t)0x0010U) /*!< PHY Link down inturrupt */
|
||||
|
||||
/* ################## SPI peripheral configuration ########################## */
|
||||
|
||||
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||
* Activated: CRC code is present inside driver
|
||||
* Deactivated: CRC code cleaned from driver
|
||||
*/
|
||||
#if !defined (USE_SPI_CRC)
|
||||
#define USE_SPI_CRC 0U
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_can.h"
|
||||
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_can_legacy.h"
|
||||
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CEC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_cec.h"
|
||||
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_cryp.h"
|
||||
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA2D_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dma2d.h"
|
||||
#endif /* HAL_DMA2D_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DCMI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dcmi.h"
|
||||
#endif /* HAL_DCMI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ETH_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_eth.h"
|
||||
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sram.h"
|
||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NOR_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_nor.h"
|
||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NAND_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_nand.h"
|
||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SDRAM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sdram.h"
|
||||
#endif /* HAL_SDRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HASH_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_hash.h"
|
||||
#endif /* HAL_HASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_lptim.h"
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LTDC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_ltdc.h"
|
||||
#endif /* HAL_LTDC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_QSPI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_qspi.h"
|
||||
#endif /* HAL_QSPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RNG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_rng.h"
|
||||
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SAI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sai.h"
|
||||
#endif /* HAL_SAI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sd.h"
|
||||
#endif /* HAL_SD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPDIFRX_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_spdifrx.h"
|
||||
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_hcd.h"
|
||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DFSDM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dfsdm.h"
|
||||
#endif /* HAL_DFSDM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DSI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dsi.h"
|
||||
#endif /* HAL_DSI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_JPEG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_jpeg.h"
|
||||
#endif /* HAL_JPEG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MDIOS_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_mdios.h"
|
||||
#endif /* HAL_MDIOS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMBUS_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_smbus.h"
|
||||
#endif /* HAL_SMBUS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MMC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_mmc.h"
|
||||
#endif /* HAL_MMC_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t *file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F7xx_HAL_CONF_DEFAULT_H */
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,185 @@
|
||||
/*
|
||||
Copyright (c) 2011 Arduino. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _VARIANT_ARDUINO_STM32_
|
||||
#define _VARIANT_ARDUINO_STM32_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Pins
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#define PG9 0
|
||||
#define PG14 1
|
||||
#define PF15 2
|
||||
#define PE13 3
|
||||
#define PF14 4
|
||||
#define PE11 5
|
||||
#define PE9 6
|
||||
#define PF13 7
|
||||
#define PF12 8
|
||||
#define PD15 9
|
||||
#define PD14 10
|
||||
#define PA7 A10
|
||||
#define PA6 A11
|
||||
#define PA5 A12
|
||||
#define PB9 14
|
||||
#define PB8 15
|
||||
#define PC6 16
|
||||
#define PB15 17
|
||||
#define PB13 18
|
||||
#define PB12 19
|
||||
#define PA15 20
|
||||
#define PC7 21
|
||||
#define PB5 22
|
||||
#define PB3 23
|
||||
#define PA4 A13
|
||||
#define PB4 25
|
||||
#define PB6 26
|
||||
#define PB2 27
|
||||
#define PD13 28
|
||||
#define PD12 29
|
||||
#define PD11 30
|
||||
#define PE2 31
|
||||
#define PA0 A14
|
||||
#define PB0 33 // LED_GREEN
|
||||
#define PE0 34
|
||||
#define PB11 35
|
||||
#define PB10 36
|
||||
#define PE15 37
|
||||
#define PE14 38
|
||||
#define PE12 39
|
||||
#define PE10 40
|
||||
#define PE7 41
|
||||
#define PE8 42
|
||||
#define PC8 43
|
||||
#define PC9 44
|
||||
#define PC10 45
|
||||
#define PC11 46
|
||||
#define PC12 47
|
||||
#define PD2 48
|
||||
#define PG2 49
|
||||
#define PG3 50
|
||||
#define PD7 51
|
||||
#define PD6 52
|
||||
#define PD5 53
|
||||
#define PD4 54
|
||||
#define PD3 55
|
||||
// 56 is PE2 (31)
|
||||
#define PE4 57
|
||||
#define PE5 58
|
||||
#define PE6 59
|
||||
#define PE3 60
|
||||
#define PF8 A15
|
||||
#define PF7 A16
|
||||
#define PF9 A17
|
||||
#define PG1 64
|
||||
#define PG0 65
|
||||
#define PD1 66
|
||||
#define PD0 67
|
||||
#define PF0 68
|
||||
#define PF1 69
|
||||
#define PF2 70
|
||||
// 71 is PA7 (11)
|
||||
// 72 is NC
|
||||
#define PB7 73 // LED_BLUE
|
||||
#define PB14 74 // LED_RED
|
||||
#define PC13 75 // USER_BTN
|
||||
#define PD9 76 // Serial Rx
|
||||
#define PD8 77 // Serial Tx
|
||||
#define PA3 A0
|
||||
#define PC0 A1
|
||||
#define PC3 A2
|
||||
#define PF3 A3
|
||||
#define PF5 A4
|
||||
#define PF10 A5
|
||||
#define PB1 A6
|
||||
#define PC2 A7
|
||||
#define PF4 A8
|
||||
#define PF6 A9
|
||||
|
||||
// This must be a literal
|
||||
#define NUM_DIGITAL_PINS 88
|
||||
// This must be a literal with a value less than or equal to to MAX_ANALOG_INPUTS
|
||||
#define NUM_ANALOG_INPUTS 18
|
||||
|
||||
// On-board LED pin number
|
||||
#define LED_BUILTIN PB0
|
||||
#define LED_GREEN LED_BUILTIN
|
||||
#define LED_BLUE PB7
|
||||
#define LED_RED PB14
|
||||
|
||||
// On-board user button
|
||||
#define USER_BTN PC13
|
||||
|
||||
// Timer Definitions
|
||||
// Use TIM6/TIM7 when possible as servo and tone don't need GPIO output pin
|
||||
#define TIMER_TONE TIM6
|
||||
#define TIMER_SERVO TIM7
|
||||
|
||||
// UART Definitions
|
||||
#define SERIAL_UART_INSTANCE 3 //Connected to ST-Link
|
||||
|
||||
// Serial pin used for console (ex: stlink)
|
||||
// Rerquired by Firmata
|
||||
#define PIN_SERIAL_RX PD9
|
||||
#define PIN_SERIAL_TX PD8
|
||||
|
||||
/* Extra HAL modules */
|
||||
#define HAL_DAC_MODULE_ENABLED
|
||||
#define HAL_ETH_MODULE_ENABLED
|
||||
|
||||
// Last Flash sector used for EEPROM emulation, address/sector depends on single/dual bank configuration.
|
||||
// By default 2MB single bank
|
||||
#define FLASH_BASE_ADDRESS 0x081C0000
|
||||
#define FLASH_DATA_SECTOR 11
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
// These serial port names are intended to allow libraries and architecture-neutral
|
||||
// sketches to automatically default to the correct port name for a particular type
|
||||
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
|
||||
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
|
||||
//
|
||||
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
|
||||
//
|
||||
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
|
||||
//
|
||||
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
|
||||
// pins are NOT connected to anything by default.
|
||||
#define SERIAL_PORT_MONITOR Serial
|
||||
|
||||
// KH mod to add Serial1, for ESP-AT
|
||||
//#define SERIAL_PORT_HARDWARE Serial
|
||||
#define SERIAL_PORT_HARDWARE Serial1
|
||||
#endif
|
||||
|
||||
#endif /* _VARIANT_ARDUINO_STM32_ */
|
@ -0,0 +1,145 @@
|
||||
/*
|
||||
Copyright (c) 2011 Arduino. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _VARIANT_ARDUINO_STM32_
|
||||
#define _VARIANT_ARDUINO_STM32_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Pins
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#define PA3 0
|
||||
#define PA2 1
|
||||
#define PA10 2
|
||||
#define PB3 3
|
||||
#define PB5 4
|
||||
#define PB4 5
|
||||
#define PB10 6
|
||||
#define PA8 7
|
||||
#define PA9 8
|
||||
#define PC7 9
|
||||
#define PB6 10
|
||||
#define PA7 A6
|
||||
#define PA6 A7
|
||||
#define PA5 13
|
||||
#define PB9 14
|
||||
#define PB8 15
|
||||
// ST Morpho
|
||||
// CN7 Left Side
|
||||
#define PC10 16
|
||||
#define PC12 17
|
||||
// 18 is NC - BOOT0
|
||||
#define PA13 19 // SWD
|
||||
#define PA14 20 // SWD
|
||||
#define PA15 21
|
||||
#define PB7 22
|
||||
#define PC13 23
|
||||
#define PC14 24
|
||||
#define PC15 25
|
||||
#define PH0 26
|
||||
#define PH1 27
|
||||
#define PC2 A8
|
||||
#define PC3 A9
|
||||
// CN7 Right Side
|
||||
#define PC11 30
|
||||
#define PD2 31
|
||||
// CN10 Left Side
|
||||
#define PC9 32
|
||||
// CN10 Right side
|
||||
#define PC8 33
|
||||
#define PC6 34
|
||||
#define PC5 A10
|
||||
#define PA12 36
|
||||
#define PA11 37
|
||||
#define PB12 38
|
||||
#define PB11 39
|
||||
#define PB2 40
|
||||
#define PB1 41
|
||||
#define PB15 42
|
||||
#define PB14 43
|
||||
#define PB13 44
|
||||
#define PC4 A11
|
||||
#define PA0 A0
|
||||
#define PA1 A1
|
||||
#define PA4 A2
|
||||
#define PB0 A3
|
||||
#define PC1 A4
|
||||
#define PC0 A5
|
||||
|
||||
// This must be a literal
|
||||
#define NUM_DIGITAL_PINS 52
|
||||
// This must be a literal with a value less than or equal to to MAX_ANALOG_INPUTS
|
||||
#define NUM_ANALOG_INPUTS 12
|
||||
|
||||
// On-board LED pin number
|
||||
#define LED_BUILTIN 13
|
||||
#define LED_GREEN LED_BUILTIN
|
||||
|
||||
// On-board user button
|
||||
#define USER_BTN PC13
|
||||
|
||||
// Timer Definitions
|
||||
// Use TIM6 when possible as servo and tone don't need GPIO output pin
|
||||
#define TIMER_TONE TIM6
|
||||
#define TIMER_SERVO TIM2
|
||||
|
||||
// UART Definitions
|
||||
#define SERIAL_UART_INSTANCE 2 //Connected to ST-Link
|
||||
// Default pin used for 'Serial' instance (ex: ST-Link)
|
||||
// Mandatory for Firmata
|
||||
#define PIN_SERIAL_RX 0
|
||||
#define PIN_SERIAL_TX 1
|
||||
|
||||
/* Extra HAL modules */
|
||||
#define HAL_DAC_MODULE_ENABLED
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
// These serial port names are intended to allow libraries and architecture-neutral
|
||||
// sketches to automatically default to the correct port name for a particular type
|
||||
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
|
||||
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
|
||||
//
|
||||
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
|
||||
//
|
||||
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
|
||||
//
|
||||
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
|
||||
// pins are NOT connected to anything by default.
|
||||
#define SERIAL_PORT_MONITOR Serial
|
||||
|
||||
// KH mod to add Serial1, for ESP-AT
|
||||
//#define SERIAL_PORT_HARDWARE Serial
|
||||
#define SERIAL_PORT_HARDWARE Serial1
|
||||
#endif
|
||||
|
||||
#endif /* _VARIANT_ARDUINO_STM32_ */
|
@ -0,0 +1,519 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_hal_conf_default.h
|
||||
* @brief HAL default configuration file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F4xx_HAL_CONF_DEFAULT_H
|
||||
#define __STM32F4xx_HAL_CONF_DEFAULT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief Include the default list of modules to be used in the HAL driver
|
||||
* and manage module deactivation
|
||||
*/
|
||||
#include "stm32yyxx_hal_conf.h"
|
||||
#if 0
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
#define HAL_MODULE_ENABLED
|
||||
#define HAL_ADC_MODULE_ENABLED
|
||||
#define HAL_CAN_MODULE_ENABLED
|
||||
/*#define HAL_CAN_LEGACY_MODULE_ENABLED*/
|
||||
#define HAL_CRC_MODULE_ENABLED
|
||||
#define HAL_CEC_MODULE_ENABLED
|
||||
#define HAL_CRYP_MODULE_ENABLED
|
||||
#define HAL_DAC_MODULE_ENABLED
|
||||
#define HAL_DCMI_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_DMA2D_MODULE_ENABLED
|
||||
#define HAL_ETH_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_NAND_MODULE_ENABLED
|
||||
#define HAL_NOR_MODULE_ENABLED
|
||||
#define HAL_PCCARD_MODULE_ENABLED
|
||||
#define HAL_SRAM_MODULE_ENABLED
|
||||
#define HAL_SDRAM_MODULE_ENABLED
|
||||
#define HAL_HASH_MODULE_ENABLED
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
#define HAL_SMBUS_MODULE_ENABLED
|
||||
#define HAL_I2S_MODULE_ENABLED
|
||||
#define HAL_IWDG_MODULE_ENABLED
|
||||
#define HAL_LTDC_MODULE_ENABLED
|
||||
#define HAL_DSI_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_QSPI_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
#define HAL_RNG_MODULE_ENABLED
|
||||
#define HAL_RTC_MODULE_ENABLED
|
||||
#define HAL_SAI_MODULE_ENABLED
|
||||
#define HAL_SD_MODULE_ENABLED
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
#define HAL_USART_MODULE_ENABLED
|
||||
#define HAL_IRDA_MODULE_ENABLED
|
||||
#define HAL_SMARTCARD_MODULE_ENABLED
|
||||
#define HAL_WWDG_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
#define HAL_PCD_MODULE_ENABLED
|
||||
#define HAL_HCD_MODULE_ENABLED
|
||||
#define HAL_FMPI2C_MODULE_ENABLED
|
||||
#define HAL_FMPSMBUS_MODULE_ENABLED
|
||||
#define HAL_SPDIFRX_MODULE_ENABLED
|
||||
#define HAL_DFSDM_MODULE_ENABLED
|
||||
#define HAL_LPTIM_MODULE_ENABLED
|
||||
#define HAL_MMC_MODULE_ENABLED
|
||||
#endif
|
||||
|
||||
/* ########################## HSE/HSI Values adaptation ##################### */
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSE is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI) value.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSI is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE 32000U /*!< LSI Typical Value in Hz */
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature. */
|
||||
/**
|
||||
* @brief External Low Speed oscillator (LSE) value.
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief External clock source for I2S peripheral
|
||||
* This value is used by the I2S HAL module to compute the I2S clock source
|
||||
* frequency, this source is inserted directly through I2S_CKIN pad.
|
||||
*/
|
||||
#if !defined (EXTERNAL_CLOCK_VALUE)
|
||||
#define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the External oscillator in Hz*/
|
||||
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
#if !defined (VDD_VALUE)
|
||||
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
|
||||
#endif
|
||||
#if !defined (TICK_INT_PRIORITY)
|
||||
#define TICK_INT_PRIORITY 0x00U /*!< tick interrupt priority */
|
||||
#endif
|
||||
#if !defined (USE_RTOS)
|
||||
#define USE_RTOS 0U
|
||||
#endif
|
||||
#if !defined (PREFETCH_ENABLE)
|
||||
#define PREFETCH_ENABLE 1U
|
||||
#endif
|
||||
#if !defined (INSTRUCTION_CACHE_ENABLE)
|
||||
#define INSTRUCTION_CACHE_ENABLE 1U
|
||||
#endif
|
||||
#if !defined (DATA_CACHE_ENABLE)
|
||||
#define DATA_CACHE_ENABLE 1U
|
||||
#endif
|
||||
|
||||
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
|
||||
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
|
||||
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
|
||||
#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */
|
||||
#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */
|
||||
#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */
|
||||
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
|
||||
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||
#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */
|
||||
#define USE_HAL_FMPSMBUS_REGISTER_CALLBACKS 0U /* FMPSMBUS register callback disabled */
|
||||
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
|
||||
#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */
|
||||
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||
#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */
|
||||
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */
|
||||
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
|
||||
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
|
||||
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
|
||||
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
|
||||
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1U */
|
||||
|
||||
/* ################## Ethernet peripheral configuration ##################### */
|
||||
|
||||
/* Section 1 : Ethernet peripheral configuration */
|
||||
|
||||
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||
#define MAC_ADDR0 2U
|
||||
#define MAC_ADDR1 0U
|
||||
#define MAC_ADDR2 0U
|
||||
#define MAC_ADDR3 0U
|
||||
#define MAC_ADDR4 0U
|
||||
#define MAC_ADDR5 0U
|
||||
|
||||
/* Definition of the Ethernet driver buffers size and count */
|
||||
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||
#define ETH_RXBUFNB (5U) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||
#define ETH_TXBUFNB (5U) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||
|
||||
/* Section 2: PHY configuration section */
|
||||
/* LAN8742A PHY Address*/
|
||||
////////////////////////////////
|
||||
//#define LAN8742A_PHY_ADDRESS 0x00U
|
||||
/* Section 2: PHY configuration section */
|
||||
#if !defined (LAN8742A_PHY_ADDRESS)
|
||||
/* LAN8742A PHY Address*/
|
||||
#define LAN8742A_PHY_ADDRESS 0x00U
|
||||
#endif
|
||||
////////////////////////////////
|
||||
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||
#define PHY_RESET_DELAY 0x000000FFU
|
||||
/* PHY Configuration delay */
|
||||
#define PHY_CONFIG_DELAY 0x00000FFFU
|
||||
|
||||
#define PHY_READ_TO 0x0000FFFFU
|
||||
#define PHY_WRITE_TO 0x0000FFFFU
|
||||
|
||||
/* Section 3: Common PHY Registers */
|
||||
|
||||
#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */
|
||||
#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */
|
||||
|
||||
#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
|
||||
#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
|
||||
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
|
||||
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
|
||||
#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
|
||||
#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
|
||||
|
||||
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
|
||||
#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
|
||||
#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
|
||||
|
||||
/* Section 4: Extended PHY Registers */
|
||||
|
||||
#define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */
|
||||
|
||||
#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */
|
||||
#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */
|
||||
|
||||
|
||||
#define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */
|
||||
#define PHY_IMR ((uint16_t)0x1E) /*!< PHY Interrupt Mask register Offset */
|
||||
#define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */
|
||||
|
||||
/* ################## SPI peripheral configuration ########################## */
|
||||
|
||||
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||
* Activated: CRC code is present inside driver
|
||||
* Deactivated: CRC code cleaned from driver
|
||||
*/
|
||||
#if !defined (USE_SPI_CRC)
|
||||
#define USE_SPI_CRC 0U
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_can.h"
|
||||
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_can_legacy.h"
|
||||
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_cryp.h"
|
||||
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA2D_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dma2d.h"
|
||||
#endif /* HAL_DMA2D_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DCMI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dcmi.h"
|
||||
#endif /* HAL_DCMI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ETH_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_eth.h"
|
||||
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sram.h"
|
||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NOR_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_nor.h"
|
||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NAND_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_nand.h"
|
||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCCARD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_pccard.h"
|
||||
#endif /* HAL_PCCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SDRAM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sdram.h"
|
||||
#endif /* HAL_SDRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HASH_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_hash.h"
|
||||
#endif /* HAL_HASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMBUS_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_smbus.h"
|
||||
#endif /* HAL_SMBUS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LTDC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_ltdc.h"
|
||||
#endif /* HAL_LTDC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RNG_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_rng.h"
|
||||
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SAI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sai.h"
|
||||
#endif /* HAL_SAI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sd.h"
|
||||
#endif /* HAL_SD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_hcd.h"
|
||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DSI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dsi.h"
|
||||
#endif /* HAL_DSI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_QSPI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_qspi.h"
|
||||
#endif /* HAL_QSPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CEC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_cec.h"
|
||||
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FMPI2C_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_fmpi2c.h"
|
||||
#endif /* HAL_FMPI2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FMPSMBUS_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_fmpsmbus.h"
|
||||
#endif /* HAL_FMPSMBUS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPDIFRX_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_spdifrx.h"
|
||||
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DFSDM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dfsdm.h"
|
||||
#endif /* HAL_DFSDM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_lptim.h"
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MMC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_mmc.h"
|
||||
#endif /* HAL_MMC_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t *file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F4xx_HAL_CONF_DEFAULT_H */
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,511 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f7xx_hal_conf_default.h
|
||||
* @brief HAL default configuration file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F7xx_HAL_CONF_DEFAULT_H
|
||||
#define __STM32F7xx_HAL_CONF_DEFAULT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief Include the default list of modules to be used in the HAL driver
|
||||
* and manage module deactivation
|
||||
*/
|
||||
#include "stm32yyxx_hal_conf.h"
|
||||
#if 0
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
#define HAL_MODULE_ENABLED
|
||||
#define HAL_ADC_MODULE_ENABLED
|
||||
#define HAL_CAN_MODULE_ENABLED
|
||||
#define HAL_CAN_LEGACY_MODULE_ENABLED
|
||||
#define HAL_CEC_MODULE_ENABLED
|
||||
#define HAL_CRC_MODULE_ENABLED
|
||||
#define HAL_CRYP_MODULE_ENABLED
|
||||
#define HAL_DAC_MODULE_ENABLED
|
||||
#define HAL_DCMI_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_DMA2D_MODULE_ENABLED
|
||||
#define HAL_ETH_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_NAND_MODULE_ENABLED
|
||||
#define HAL_NOR_MODULE_ENABLED
|
||||
#define HAL_SRAM_MODULE_ENABLED
|
||||
#define HAL_SDRAM_MODULE_ENABLED
|
||||
#define HAL_HASH_MODULE_ENABLED
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
#define HAL_I2S_MODULE_ENABLED
|
||||
#define HAL_IWDG_MODULE_ENABLED
|
||||
#define HAL_LPTIM_MODULE_ENABLED
|
||||
#define HAL_LTDC_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_QSPI_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
#define HAL_RNG_MODULE_ENABLED
|
||||
#define HAL_RTC_MODULE_ENABLED
|
||||
#define HAL_SAI_MODULE_ENABLED
|
||||
#define HAL_SD_MODULE_ENABLED
|
||||
#define HAL_SPDIFRX_MODULE_ENABLED
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
#define HAL_USART_MODULE_ENABLED
|
||||
#define HAL_IRDA_MODULE_ENABLED
|
||||
#define HAL_SMARTCARD_MODULE_ENABLED
|
||||
#define HAL_WWDG_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
#define HAL_PCD_MODULE_ENABLED
|
||||
#define HAL_HCD_MODULE_ENABLED
|
||||
#define HAL_DFSDM_MODULE_ENABLED
|
||||
#define HAL_DSI_MODULE_ENABLED
|
||||
#define HAL_JPEG_MODULE_ENABLED
|
||||
#define HAL_MDIOS_MODULE_ENABLED
|
||||
#define HAL_SMBUS_MODULE_ENABLED
|
||||
#define HAL_MMC_MODULE_ENABLED
|
||||
#endif
|
||||
|
||||
/* ########################## HSE/HSI Values adaptation ##################### */
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSE is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI) value.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSI is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature. */
|
||||
/**
|
||||
* @brief External Low Speed oscillator (LSE) value.
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief External clock source for I2S peripheral
|
||||
* This value is used by the I2S HAL module to compute the I2S clock source
|
||||
* frequency, this source is inserted directly through I2S_CKIN pad.
|
||||
*/
|
||||
#if !defined (EXTERNAL_CLOCK_VALUE)
|
||||
#define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
#if !defined (VDD_VALUE)
|
||||
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
|
||||
#endif
|
||||
#if !defined (TICK_INT_PRIORITY)
|
||||
#define TICK_INT_PRIORITY 0x00U /*!< tick interrupt priority */
|
||||
#endif
|
||||
#if !defined (USE_RTOS)
|
||||
#define USE_RTOS 0U
|
||||
#endif
|
||||
#if !defined (PREFETCH_ENABLE)
|
||||
#define PREFETCH_ENABLE 1U /* To enable prefetch */
|
||||
#endif
|
||||
#if !defined (ART_ACCLERATOR_ENABLE)
|
||||
#define ART_ACCLERATOR_ENABLE 1U /* To enable ART Accelerator */
|
||||
#endif
|
||||
|
||||
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
|
||||
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
|
||||
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
|
||||
#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */
|
||||
#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */
|
||||
#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */
|
||||
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
|
||||
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||
#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */
|
||||
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
|
||||
#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */
|
||||
#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIOS register callback disabled */
|
||||
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */
|
||||
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
|
||||
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
|
||||
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
|
||||
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
|
||||
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1 */
|
||||
|
||||
/* ################## Ethernet peripheral configuration ##################### */
|
||||
|
||||
/* Section 1 : Ethernet peripheral configuration */
|
||||
|
||||
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||
#define MAC_ADDR0 2U
|
||||
#define MAC_ADDR1 0U
|
||||
#define MAC_ADDR2 0U
|
||||
#define MAC_ADDR3 0U
|
||||
#define MAC_ADDR4 0U
|
||||
#define MAC_ADDR5 0U
|
||||
|
||||
/* Definition of the Ethernet driver buffers size and count */
|
||||
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||
#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||
#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||
|
||||
/* Section 2: PHY configuration section */
|
||||
/* LAN8742A PHY Address*/
|
||||
////////////////////////////////
|
||||
//#define LAN8742A_PHY_ADDRESS 0x00U
|
||||
/* Section 2: PHY configuration section */
|
||||
#if !defined (LAN8742A_PHY_ADDRESS)
|
||||
/* LAN8742A PHY Address*/
|
||||
#define LAN8742A_PHY_ADDRESS 0x00U
|
||||
#endif
|
||||
////////////////////////////////
|
||||
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||
#define PHY_RESET_DELAY 0x00000FFFU
|
||||
/* PHY Configuration delay */
|
||||
#define PHY_CONFIG_DELAY 0x00000FFFU
|
||||
|
||||
#define PHY_READ_TO 0x0000FFFFU
|
||||
#define PHY_WRITE_TO 0x0000FFFFU
|
||||
|
||||
/* Section 3: Common PHY Registers */
|
||||
|
||||
#define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */
|
||||
#define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */
|
||||
|
||||
#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
|
||||
#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
|
||||
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
|
||||
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
|
||||
#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
|
||||
#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
|
||||
|
||||
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
|
||||
#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
|
||||
#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
|
||||
|
||||
/* Section 4: Extended PHY Registers */
|
||||
|
||||
#define PHY_SR ((uint16_t)0x1FU) /*!< PHY special control/ status register Offset */
|
||||
|
||||
#define PHY_SPEED_STATUS ((uint16_t)0x0004U) /*!< PHY Speed mask */
|
||||
#define PHY_DUPLEX_STATUS ((uint16_t)0x0010U) /*!< PHY Duplex mask */
|
||||
|
||||
|
||||
#define PHY_ISFR ((uint16_t)0x01DU) /*!< PHY Interrupt Source Flag register Offset */
|
||||
#define PHY_IMR ((uint16_t)0x001E) /*!< PHY Interrupt Mask register Offset */
|
||||
#define PHY_ISFR_INT4 ((uint16_t)0x0010U) /*!< PHY Link down inturrupt */
|
||||
|
||||
/* ################## SPI peripheral configuration ########################## */
|
||||
|
||||
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||
* Activated: CRC code is present inside driver
|
||||
* Deactivated: CRC code cleaned from driver
|
||||
*/
|
||||
#if !defined (USE_SPI_CRC)
|
||||
#define USE_SPI_CRC 0U
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_can.h"
|
||||
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_can_legacy.h"
|
||||
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CEC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_cec.h"
|
||||
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_cryp.h"
|
||||
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA2D_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dma2d.h"
|
||||
#endif /* HAL_DMA2D_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DCMI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dcmi.h"
|
||||
#endif /* HAL_DCMI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ETH_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_eth.h"
|
||||
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sram.h"
|
||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NOR_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_nor.h"
|
||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NAND_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_nand.h"
|
||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SDRAM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sdram.h"
|
||||
#endif /* HAL_SDRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HASH_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_hash.h"
|
||||
#endif /* HAL_HASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_lptim.h"
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LTDC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_ltdc.h"
|
||||
#endif /* HAL_LTDC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_QSPI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_qspi.h"
|
||||
#endif /* HAL_QSPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RNG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_rng.h"
|
||||
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SAI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sai.h"
|
||||
#endif /* HAL_SAI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sd.h"
|
||||
#endif /* HAL_SD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPDIFRX_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_spdifrx.h"
|
||||
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_hcd.h"
|
||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DFSDM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dfsdm.h"
|
||||
#endif /* HAL_DFSDM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DSI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dsi.h"
|
||||
#endif /* HAL_DSI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_JPEG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_jpeg.h"
|
||||
#endif /* HAL_JPEG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MDIOS_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_mdios.h"
|
||||
#endif /* HAL_MDIOS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMBUS_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_smbus.h"
|
||||
#endif /* HAL_SMBUS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MMC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_mmc.h"
|
||||
#endif /* HAL_MMC_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t *file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F7xx_HAL_CONF_DEFAULT_H */
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,274 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2020-2021, STMicroelectronics
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Pins
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#define PG9 0
|
||||
#define PG14 1
|
||||
#define PF15 2
|
||||
#define PE13 3
|
||||
#define PF14 4
|
||||
#define PE11 5
|
||||
#define PE9 6
|
||||
#define PF13 7
|
||||
#define PF12 8
|
||||
#define PD15 9
|
||||
#define PD14 10
|
||||
#define PA7 PIN_A10
|
||||
#define PA6 PIN_A11
|
||||
#define PA5 PIN_A12
|
||||
#define PB9 14
|
||||
#define PB8 15
|
||||
#define PC6 16
|
||||
#define PB15 17
|
||||
#define PB13 18
|
||||
#define PB12 19
|
||||
#define PA15 20
|
||||
#define PC7 21
|
||||
#define PB5 22
|
||||
#define PB3 23
|
||||
#define PA4 PIN_A13
|
||||
#define PB4 25
|
||||
#define PB6 26
|
||||
#define PB2 27
|
||||
#define PD13 28
|
||||
#define PD12 29
|
||||
#define PD11 30
|
||||
#define PE2 31
|
||||
#define PA0 PIN_A14
|
||||
#define PB0 PIN_A23 // LED_GREEN
|
||||
#define PE0 34
|
||||
#define PB11 35
|
||||
#define PB10 36
|
||||
#define PE15 37
|
||||
#define PE14 38
|
||||
#define PE12 39
|
||||
#define PE10 40
|
||||
#define PE7 41
|
||||
#define PE8 42
|
||||
#define PC8 43
|
||||
#define PC9 44
|
||||
#define PC10 45
|
||||
#define PC11 46
|
||||
#define PC12 47
|
||||
#define PD2 48
|
||||
#define PG2 49
|
||||
#define PG3 50
|
||||
#define PD7 51
|
||||
#define PD6 52
|
||||
#define PD5 53
|
||||
#define PD4 54
|
||||
#define PD3 55
|
||||
// 56 is PE2 (31)
|
||||
#define PE4 57
|
||||
#define PE5 58
|
||||
#define PE6 59
|
||||
#define PE3 60
|
||||
#define PF8 PIN_A15
|
||||
#define PF7 PIN_A16
|
||||
#define PF9 PIN_A17
|
||||
#define PG1 64
|
||||
#define PG0 65
|
||||
#define PD1 66
|
||||
#define PD0 67
|
||||
#define PF0 68
|
||||
#define PF1 69
|
||||
#define PF2 70
|
||||
// 71 is PA7 (11)
|
||||
// 72 is NC
|
||||
#define PB7 73 // LED_BLUE
|
||||
#define PB14 74 // LED_RED
|
||||
#define PC13 75 // USER_BTN
|
||||
#define PD9 76 // Serial Rx
|
||||
#define PD8 77 // Serial Tx
|
||||
#define PA3 PIN_A0
|
||||
#define PC0 PIN_A1
|
||||
#define PC3 PIN_A2
|
||||
#define PF3 PIN_A3
|
||||
#define PF5 PIN_A4
|
||||
#define PF10 PIN_A5
|
||||
#define PB1 PIN_A6
|
||||
#define PC2 PIN_A7
|
||||
#define PF4 PIN_A8
|
||||
#define PF6 PIN_A9
|
||||
// ST Morpho
|
||||
#define PA1 PIN_A18
|
||||
#define PA2 PIN_A19
|
||||
#define PA8 90
|
||||
#define PA9 91
|
||||
#define PA10 92
|
||||
#define PA11 93
|
||||
#define PA12 94
|
||||
#define PA13 95 // SWD
|
||||
#define PA14 96 // SWD
|
||||
#define PC1 PIN_A20
|
||||
#define PC4 PIN_A21
|
||||
#define PC5 PIN_A22
|
||||
#define PC14 100
|
||||
#define PC15 101
|
||||
#define PD10 102
|
||||
#define PE1 103
|
||||
#define PF11 104
|
||||
#define PG4 105
|
||||
#define PG5 106
|
||||
#define PG6 107
|
||||
#define PG7 108
|
||||
#define PG8 109
|
||||
#define PG10 110
|
||||
#define PG11 111
|
||||
#define PG12 112
|
||||
#define PG13 113
|
||||
#define PG15 114
|
||||
#define PH0 115 // MCO
|
||||
#define PH1 116
|
||||
|
||||
// Alternate pins number
|
||||
#define PA0_ALT1 (PA0 | ALT1)
|
||||
#define PA0_ALT2 (PA0 | ALT2)
|
||||
#define PA1_ALT1 (PA1 | ALT1)
|
||||
#define PA1_ALT2 (PA1 | ALT2)
|
||||
#define PA2_ALT1 (PA2 | ALT1)
|
||||
#define PA2_ALT2 (PA2 | ALT2)
|
||||
#define PA3_ALT1 (PA3 | ALT1)
|
||||
#define PA3_ALT2 (PA3 | ALT2)
|
||||
#define PA4_ALT1 (PA4 | ALT1)
|
||||
#define PA5_ALT1 (PA5 | ALT1)
|
||||
#define PA6_ALT1 (PA6 | ALT1)
|
||||
#define PA7_ALT1 (PA7 | ALT1)
|
||||
#define PA7_ALT2 (PA7 | ALT2)
|
||||
#define PA7_ALT3 (PA7 | ALT3)
|
||||
#define PA15_ALT1 (PA15 | ALT1)
|
||||
#define PB0_ALT1 (PB0 | ALT1)
|
||||
#define PB0_ALT2 (PB0 | ALT2)
|
||||
#define PB1_ALT1 (PB1 | ALT1)
|
||||
#define PB1_ALT2 (PB1 | ALT2)
|
||||
#define PB3_ALT1 (PB3 | ALT1)
|
||||
#define PB4_ALT1 (PB4 | ALT1)
|
||||
#define PB5_ALT1 (PB5 | ALT1)
|
||||
#define PB8_ALT1 (PB8 | ALT1)
|
||||
#define PB9_ALT1 (PB9 | ALT1)
|
||||
#define PB14_ALT1 (PB14 | ALT1)
|
||||
#define PB14_ALT2 (PB14 | ALT2)
|
||||
#define PB15_ALT1 (PB15 | ALT1)
|
||||
#define PB15_ALT2 (PB15 | ALT2)
|
||||
#define PC0_ALT1 (PC0 | ALT1)
|
||||
#define PC0_ALT2 (PC0 | ALT2)
|
||||
#define PC1_ALT1 (PC1 | ALT1)
|
||||
#define PC1_ALT2 (PC1 | ALT2)
|
||||
#define PC2_ALT1 (PC2 | ALT1)
|
||||
#define PC2_ALT2 (PC2 | ALT2)
|
||||
#define PC3_ALT1 (PC3 | ALT1)
|
||||
#define PC3_ALT2 (PC3 | ALT2)
|
||||
#define PC4_ALT1 (PC4 | ALT1)
|
||||
#define PC5_ALT1 (PC5 | ALT1)
|
||||
#define PC6_ALT1 (PC6 | ALT1)
|
||||
#define PC7_ALT1 (PC7 | ALT1)
|
||||
#define PC8_ALT1 (PC8 | ALT1)
|
||||
#define PC9_ALT1 (PC9 | ALT1)
|
||||
#define PC10_ALT1 (PC10 | ALT1)
|
||||
#define PC11_ALT1 (PC11 | ALT1)
|
||||
|
||||
// This must be a literal
|
||||
#define NUM_DIGITAL_PINS 117
|
||||
// This must be a literal with a value less than or equal to to MAX_ANALOG_INPUTS
|
||||
#define NUM_ANALOG_INPUTS 24
|
||||
|
||||
// On-board LED pin number
|
||||
#ifndef LED_BUILTIN
|
||||
#define LED_BUILTIN PB0
|
||||
#endif
|
||||
#define LED_GREEN LED_BUILTIN
|
||||
#define LED_BLUE PB7
|
||||
#define LED_RED PB14
|
||||
|
||||
// On-board user button
|
||||
#ifndef USER_BTN
|
||||
#define USER_BTN PC13
|
||||
#endif
|
||||
|
||||
// Timer Definitions
|
||||
// Use TIM6/TIM7 when possible as servo and tone don't need GPIO output pin
|
||||
#ifndef TIMER_TONE
|
||||
#define TIMER_TONE TIM6
|
||||
#endif
|
||||
#ifndef TIMER_SERVO
|
||||
#define TIMER_SERVO TIM7
|
||||
#endif
|
||||
|
||||
// UART Definitions
|
||||
#ifndef SERIAL_UART_INSTANCE
|
||||
#define SERIAL_UART_INSTANCE 3 //Connected to ST-Link
|
||||
#endif
|
||||
// Serial pin used for console (ex: stlink)
|
||||
// Rerquired by Firmata
|
||||
#ifndef PIN_SERIAL_RX
|
||||
#define PIN_SERIAL_RX PD9
|
||||
#endif
|
||||
#ifndef PIN_SERIAL_TX
|
||||
#define PIN_SERIAL_TX PD8
|
||||
#endif
|
||||
|
||||
// Value of the External oscillator in Hz
|
||||
#define HSE_VALUE 8000000U
|
||||
|
||||
/* Extra HAL modules */
|
||||
#if !defined(HAL_DAC_MODULE_DISABLED)
|
||||
#define HAL_DAC_MODULE_ENABLED
|
||||
#endif
|
||||
#if !defined(HAL_ETH_MODULE_DISABLED)
|
||||
#define HAL_ETH_MODULE_ENABLED
|
||||
#endif
|
||||
#if !defined(HAL_QSPI_MODULE_DISABLED)
|
||||
#define HAL_QSPI_MODULE_ENABLED
|
||||
#endif
|
||||
#if !defined(HAL_SD_MODULE_DISABLED)
|
||||
#define HAL_SD_MODULE_ENABLED
|
||||
#endif
|
||||
|
||||
// Last Flash sector used for EEPROM emulation, address/sector depends on single/dual bank configuration.
|
||||
// By default 2MB single bank
|
||||
#define FLASH_BASE_ADDRESS 0x081C0000
|
||||
#define FLASH_DATA_SECTOR 11
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
// These serial port names are intended to allow libraries and architecture-neutral
|
||||
// sketches to automatically default to the correct port name for a particular type
|
||||
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
|
||||
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
|
||||
//
|
||||
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
|
||||
//
|
||||
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
|
||||
//
|
||||
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
|
||||
// pins are NOT connected to anything by default.
|
||||
#ifndef SERIAL_PORT_MONITOR
|
||||
#define SERIAL_PORT_MONITOR Serial
|
||||
#endif
|
||||
#ifndef SERIAL_PORT_HARDWARE
|
||||
// KH mod to add Serial1, for ESP-AT
|
||||
//#define SERIAL_PORT_HARDWARE Serial
|
||||
#define SERIAL_PORT_HARDWARE Serial1
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2020-2021, STMicroelectronics
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* STM32 pins number
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define PA0 PIN_A0
|
||||
#define PA1 PIN_A1
|
||||
#define PA2 PIN_A2
|
||||
#define PA3 PIN_A3
|
||||
#define PA4 PIN_A4
|
||||
#define PA5 PIN_A5
|
||||
#define PA6 PIN_A6
|
||||
#define PA7 PIN_A7
|
||||
#define PA8 8
|
||||
#define PA9 9
|
||||
#define PA10 10
|
||||
#define PA11 11
|
||||
#define PA12 12
|
||||
#define PA13 13
|
||||
#define PA14 14
|
||||
#define PA15 15
|
||||
#define PB0 PIN_A8
|
||||
#define PB1 PIN_A9
|
||||
#define PB2 18
|
||||
#define PB3 19
|
||||
#define PB4 20
|
||||
#define PB5 21
|
||||
#define PB6 22
|
||||
#define PB7 23
|
||||
#define PB8 24
|
||||
#define PB9 25
|
||||
#define PB10 26
|
||||
#define PB11 27
|
||||
#define PB12 28
|
||||
#define PB13 29
|
||||
#define PB14 30
|
||||
#define PB15 31
|
||||
#define PC0 PIN_A10
|
||||
#define PC1 PIN_A11
|
||||
#define PC2 PIN_A12
|
||||
#define PC4 PIN_A13
|
||||
#define PC5 PIN_A14
|
||||
#define PC6 37
|
||||
#define PC7 38
|
||||
#define PC8 39
|
||||
#define PC9 40
|
||||
#define PC10 41
|
||||
#define PC11 42
|
||||
#define PC12 43
|
||||
#define PC13 44
|
||||
#define PC14 45
|
||||
#define PC15 46
|
||||
#define PD2 47
|
||||
#define PH0 48
|
||||
#define PH1 49
|
||||
|
||||
// Alternate pins number
|
||||
#define PA2_ALT1 (PA2 | ALT1)
|
||||
#define PA3_ALT1 (PA3 | ALT1)
|
||||
|
||||
#define NUM_DIGITAL_PINS 50
|
||||
#define NUM_ANALOG_INPUTS 15
|
||||
|
||||
// On-board LED pin number
|
||||
#ifndef LED_BUILTIN
|
||||
#define LED_BUILTIN PNUM_NOT_DEFINED
|
||||
#endif
|
||||
|
||||
// On-board user button
|
||||
#ifndef USER_BTN
|
||||
#define USER_BTN PNUM_NOT_DEFINED
|
||||
#endif
|
||||
|
||||
// SPI definitions
|
||||
#ifndef PIN_SPI_SS
|
||||
#define PIN_SPI_SS PA4
|
||||
#endif
|
||||
#ifndef PIN_SPI_SS1
|
||||
#define PIN_SPI_SS1 PA15
|
||||
#endif
|
||||
#ifndef PIN_SPI_SS2
|
||||
#define PIN_SPI_SS2 PNUM_NOT_DEFINED
|
||||
#endif
|
||||
#ifndef PIN_SPI_SS3
|
||||
#define PIN_SPI_SS3 PNUM_NOT_DEFINED
|
||||
#endif
|
||||
#ifndef PIN_SPI_MOSI
|
||||
#define PIN_SPI_MOSI PA7
|
||||
#endif
|
||||
#ifndef PIN_SPI_MISO
|
||||
#define PIN_SPI_MISO PA6
|
||||
#endif
|
||||
#ifndef PIN_SPI_SCK
|
||||
#define PIN_SPI_SCK PA5
|
||||
#endif
|
||||
|
||||
// I2C definitions
|
||||
#ifndef PIN_WIRE_SDA
|
||||
#define PIN_WIRE_SDA PB7
|
||||
#endif
|
||||
#ifndef PIN_WIRE_SCL
|
||||
#define PIN_WIRE_SCL PB6
|
||||
#endif
|
||||
|
||||
// Timer Definitions
|
||||
// Use TIM6/TIM7 when possible as servo and tone don't need GPIO output pin
|
||||
#ifndef TIMER_TONE
|
||||
#define TIMER_TONE TIM6
|
||||
#endif
|
||||
#ifndef TIMER_SERVO
|
||||
#define TIMER_SERVO TIM21
|
||||
#endif
|
||||
|
||||
// UART Definitions
|
||||
#ifndef SERIAL_UART_INSTANCE
|
||||
#define SERIAL_UART_INSTANCE 2
|
||||
#endif
|
||||
|
||||
// Default pin used for generic 'Serial' instance
|
||||
// Mandatory for Firmata
|
||||
#ifndef PIN_SERIAL_RX
|
||||
#define PIN_SERIAL_RX PA3
|
||||
#endif
|
||||
#ifndef PIN_SERIAL_TX
|
||||
#define PIN_SERIAL_TX PA2
|
||||
#endif
|
||||
|
||||
// Extra HAL modules
|
||||
#if !defined(HAL_DAC_MODULE_DISABLED)
|
||||
#define HAL_DAC_MODULE_ENABLED
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
// These serial port names are intended to allow libraries and architecture-neutral
|
||||
// sketches to automatically default to the correct port name for a particular type
|
||||
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
|
||||
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
|
||||
//
|
||||
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
|
||||
//
|
||||
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
|
||||
//
|
||||
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
|
||||
// pins are NOT connected to anything by default.
|
||||
#ifndef SERIAL_PORT_MONITOR
|
||||
#define SERIAL_PORT_MONITOR Serial
|
||||
#endif
|
||||
#ifndef SERIAL_PORT_HARDWARE
|
||||
// KH mod to add Serial1, for ESP-AT
|
||||
//#define SERIAL_PORT_HARDWARE Serial
|
||||
#define SERIAL_PORT_HARDWARE Serial1
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,274 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2020-2021, STMicroelectronics
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Pins
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#define PG9 0
|
||||
#define PG14 1
|
||||
#define PF15 2
|
||||
#define PE13 3
|
||||
#define PF14 4
|
||||
#define PE11 5
|
||||
#define PE9 6
|
||||
#define PF13 7
|
||||
#define PF12 8
|
||||
#define PD15 9
|
||||
#define PD14 10
|
||||
#define PA7 PIN_A10
|
||||
#define PA6 PIN_A11
|
||||
#define PA5 PIN_A12
|
||||
#define PB9 14
|
||||
#define PB8 15
|
||||
#define PC6 16
|
||||
#define PB15 17
|
||||
#define PB13 18
|
||||
#define PB12 19
|
||||
#define PA15 20
|
||||
#define PC7 21
|
||||
#define PB5 22
|
||||
#define PB3 23
|
||||
#define PA4 PIN_A13
|
||||
#define PB4 25
|
||||
#define PB6 26
|
||||
#define PB2 27
|
||||
#define PD13 28
|
||||
#define PD12 29
|
||||
#define PD11 30
|
||||
#define PE2 31
|
||||
#define PA0 PIN_A14
|
||||
#define PB0 PIN_A23 // LED_GREEN
|
||||
#define PE0 34
|
||||
#define PB11 35
|
||||
#define PB10 36
|
||||
#define PE15 37
|
||||
#define PE14 38
|
||||
#define PE12 39
|
||||
#define PE10 40
|
||||
#define PE7 41
|
||||
#define PE8 42
|
||||
#define PC8 43
|
||||
#define PC9 44
|
||||
#define PC10 45
|
||||
#define PC11 46
|
||||
#define PC12 47
|
||||
#define PD2 48
|
||||
#define PG2 49
|
||||
#define PG3 50
|
||||
#define PD7 51
|
||||
#define PD6 52
|
||||
#define PD5 53
|
||||
#define PD4 54
|
||||
#define PD3 55
|
||||
// 56 is PE2 (31)
|
||||
#define PE4 57
|
||||
#define PE5 58
|
||||
#define PE6 59
|
||||
#define PE3 60
|
||||
#define PF8 PIN_A15
|
||||
#define PF7 PIN_A16
|
||||
#define PF9 PIN_A17
|
||||
#define PG1 64
|
||||
#define PG0 65
|
||||
#define PD1 66
|
||||
#define PD0 67
|
||||
#define PF0 68
|
||||
#define PF1 69
|
||||
#define PF2 70
|
||||
// 71 is PA7 (11)
|
||||
// 72 is NC
|
||||
#define PB7 73 // LED_BLUE
|
||||
#define PB14 74 // LED_RED
|
||||
#define PC13 75 // USER_BTN
|
||||
#define PD9 76 // Serial Rx
|
||||
#define PD8 77 // Serial Tx
|
||||
#define PA3 PIN_A0
|
||||
#define PC0 PIN_A1
|
||||
#define PC3 PIN_A2
|
||||
#define PF3 PIN_A3
|
||||
#define PF5 PIN_A4
|
||||
#define PF10 PIN_A5
|
||||
#define PB1 PIN_A6
|
||||
#define PC2 PIN_A7
|
||||
#define PF4 PIN_A8
|
||||
#define PF6 PIN_A9
|
||||
// ST Morpho
|
||||
#define PA1 PIN_A18
|
||||
#define PA2 PIN_A19
|
||||
#define PA8 90
|
||||
#define PA9 91
|
||||
#define PA10 92
|
||||
#define PA11 93
|
||||
#define PA12 94
|
||||
#define PA13 95 // SWD
|
||||
#define PA14 96 // SWD
|
||||
#define PC1 PIN_A20
|
||||
#define PC4 PIN_A21
|
||||
#define PC5 PIN_A22
|
||||
#define PC14 100
|
||||
#define PC15 101
|
||||
#define PD10 102
|
||||
#define PE1 103
|
||||
#define PF11 104
|
||||
#define PG4 105
|
||||
#define PG5 106
|
||||
#define PG6 107
|
||||
#define PG7 108
|
||||
#define PG8 109
|
||||
#define PG10 110
|
||||
#define PG11 111
|
||||
#define PG12 112
|
||||
#define PG13 113
|
||||
#define PG15 114
|
||||
#define PH0 115 // MCO
|
||||
#define PH1 116
|
||||
|
||||
// Alternate pins number
|
||||
#define PA0_ALT1 (PA0 | ALT1)
|
||||
#define PA0_ALT2 (PA0 | ALT2)
|
||||
#define PA1_ALT1 (PA1 | ALT1)
|
||||
#define PA1_ALT2 (PA1 | ALT2)
|
||||
#define PA2_ALT1 (PA2 | ALT1)
|
||||
#define PA2_ALT2 (PA2 | ALT2)
|
||||
#define PA3_ALT1 (PA3 | ALT1)
|
||||
#define PA3_ALT2 (PA3 | ALT2)
|
||||
#define PA4_ALT1 (PA4 | ALT1)
|
||||
#define PA5_ALT1 (PA5 | ALT1)
|
||||
#define PA6_ALT1 (PA6 | ALT1)
|
||||
#define PA7_ALT1 (PA7 | ALT1)
|
||||
#define PA7_ALT2 (PA7 | ALT2)
|
||||
#define PA7_ALT3 (PA7 | ALT3)
|
||||
#define PA15_ALT1 (PA15 | ALT1)
|
||||
#define PB0_ALT1 (PB0 | ALT1)
|
||||
#define PB0_ALT2 (PB0 | ALT2)
|
||||
#define PB1_ALT1 (PB1 | ALT1)
|
||||
#define PB1_ALT2 (PB1 | ALT2)
|
||||
#define PB3_ALT1 (PB3 | ALT1)
|
||||
#define PB4_ALT1 (PB4 | ALT1)
|
||||
#define PB5_ALT1 (PB5 | ALT1)
|
||||
#define PB8_ALT1 (PB8 | ALT1)
|
||||
#define PB9_ALT1 (PB9 | ALT1)
|
||||
#define PB14_ALT1 (PB14 | ALT1)
|
||||
#define PB14_ALT2 (PB14 | ALT2)
|
||||
#define PB15_ALT1 (PB15 | ALT1)
|
||||
#define PB15_ALT2 (PB15 | ALT2)
|
||||
#define PC0_ALT1 (PC0 | ALT1)
|
||||
#define PC0_ALT2 (PC0 | ALT2)
|
||||
#define PC1_ALT1 (PC1 | ALT1)
|
||||
#define PC1_ALT2 (PC1 | ALT2)
|
||||
#define PC2_ALT1 (PC2 | ALT1)
|
||||
#define PC2_ALT2 (PC2 | ALT2)
|
||||
#define PC3_ALT1 (PC3 | ALT1)
|
||||
#define PC3_ALT2 (PC3 | ALT2)
|
||||
#define PC4_ALT1 (PC4 | ALT1)
|
||||
#define PC5_ALT1 (PC5 | ALT1)
|
||||
#define PC6_ALT1 (PC6 | ALT1)
|
||||
#define PC7_ALT1 (PC7 | ALT1)
|
||||
#define PC8_ALT1 (PC8 | ALT1)
|
||||
#define PC9_ALT1 (PC9 | ALT1)
|
||||
#define PC10_ALT1 (PC10 | ALT1)
|
||||
#define PC11_ALT1 (PC11 | ALT1)
|
||||
|
||||
// This must be a literal
|
||||
#define NUM_DIGITAL_PINS 117
|
||||
// This must be a literal with a value less than or equal to to MAX_ANALOG_INPUTS
|
||||
#define NUM_ANALOG_INPUTS 24
|
||||
|
||||
// On-board LED pin number
|
||||
#ifndef LED_BUILTIN
|
||||
#define LED_BUILTIN PB0
|
||||
#endif
|
||||
#define LED_GREEN LED_BUILTIN
|
||||
#define LED_BLUE PB7
|
||||
#define LED_RED PB14
|
||||
|
||||
// On-board user button
|
||||
#ifndef USER_BTN
|
||||
#define USER_BTN PC13
|
||||
#endif
|
||||
|
||||
// Timer Definitions
|
||||
// Use TIM6/TIM7 when possible as servo and tone don't need GPIO output pin
|
||||
#ifndef TIMER_TONE
|
||||
#define TIMER_TONE TIM6
|
||||
#endif
|
||||
#ifndef TIMER_SERVO
|
||||
#define TIMER_SERVO TIM7
|
||||
#endif
|
||||
|
||||
// UART Definitions
|
||||
#ifndef SERIAL_UART_INSTANCE
|
||||
#define SERIAL_UART_INSTANCE 3 //Connected to ST-Link
|
||||
#endif
|
||||
// Serial pin used for console (ex: stlink)
|
||||
// Rerquired by Firmata
|
||||
#ifndef PIN_SERIAL_RX
|
||||
#define PIN_SERIAL_RX PD9
|
||||
#endif
|
||||
#ifndef PIN_SERIAL_TX
|
||||
#define PIN_SERIAL_TX PD8
|
||||
#endif
|
||||
|
||||
// Value of the External oscillator in Hz
|
||||
#define HSE_VALUE 8000000U
|
||||
|
||||
/* Extra HAL modules */
|
||||
#if !defined(HAL_DAC_MODULE_DISABLED)
|
||||
#define HAL_DAC_MODULE_ENABLED
|
||||
#endif
|
||||
#if !defined(HAL_ETH_MODULE_DISABLED)
|
||||
#define HAL_ETH_MODULE_ENABLED
|
||||
#endif
|
||||
#if !defined(HAL_QSPI_MODULE_DISABLED)
|
||||
#define HAL_QSPI_MODULE_ENABLED
|
||||
#endif
|
||||
#if !defined(HAL_SD_MODULE_DISABLED)
|
||||
#define HAL_SD_MODULE_ENABLED
|
||||
#endif
|
||||
|
||||
// Last Flash sector used for EEPROM emulation, address/sector depends on single/dual bank configuration.
|
||||
// By default 2MB single bank
|
||||
#define FLASH_BASE_ADDRESS 0x081C0000
|
||||
#define FLASH_DATA_SECTOR 11
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
// These serial port names are intended to allow libraries and architecture-neutral
|
||||
// sketches to automatically default to the correct port name for a particular type
|
||||
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
|
||||
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
|
||||
//
|
||||
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
|
||||
//
|
||||
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
|
||||
//
|
||||
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
|
||||
// pins are NOT connected to anything by default.
|
||||
#ifndef SERIAL_PORT_MONITOR
|
||||
#define SERIAL_PORT_MONITOR Serial
|
||||
#endif
|
||||
#ifndef SERIAL_PORT_HARDWARE
|
||||
// KH mod to add Serial1, for ESP-AT
|
||||
//#define SERIAL_PORT_HARDWARE Serial
|
||||
#define SERIAL_PORT_HARDWARE Serial1
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2020-2021, STMicroelectronics
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* STM32 pins number
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define PA0 PIN_A0
|
||||
#define PA1 PIN_A1
|
||||
#define PA2 PIN_A2
|
||||
#define PA3 PIN_A3
|
||||
#define PA4 PIN_A4
|
||||
#define PA5 PIN_A5
|
||||
#define PA6 PIN_A6
|
||||
#define PA7 PIN_A7
|
||||
#define PA8 8
|
||||
#define PA9 9
|
||||
#define PA10 10
|
||||
#define PA11 11
|
||||
#define PA12 12
|
||||
#define PA13 13
|
||||
#define PA14 14
|
||||
#define PA15 15
|
||||
#define PB0 PIN_A8
|
||||
#define PB1 PIN_A9
|
||||
#define PB2 18
|
||||
#define PB3 19
|
||||
#define PB4 20
|
||||
#define PB5 21
|
||||
#define PB6 22
|
||||
#define PB7 23
|
||||
#define PB8 24
|
||||
#define PB9 25
|
||||
#define PB10 26
|
||||
#define PB11 27
|
||||
#define PB12 28
|
||||
#define PB13 29
|
||||
#define PB14 30
|
||||
#define PB15 31
|
||||
#define PC0 PIN_A10
|
||||
#define PC1 PIN_A11
|
||||
#define PC2 PIN_A12
|
||||
#define PC4 PIN_A13
|
||||
#define PC5 PIN_A14
|
||||
#define PC6 37
|
||||
#define PC7 38
|
||||
#define PC8 39
|
||||
#define PC9 40
|
||||
#define PC10 41
|
||||
#define PC11 42
|
||||
#define PC12 43
|
||||
#define PC13 44
|
||||
#define PC14 45
|
||||
#define PC15 46
|
||||
#define PD2 47
|
||||
#define PH0 48
|
||||
#define PH1 49
|
||||
|
||||
// Alternate pins number
|
||||
#define PA2_ALT1 (PA2 | ALT1)
|
||||
#define PA3_ALT1 (PA3 | ALT1)
|
||||
|
||||
#define NUM_DIGITAL_PINS 50
|
||||
#define NUM_ANALOG_INPUTS 15
|
||||
|
||||
// On-board LED pin number
|
||||
#ifndef LED_BUILTIN
|
||||
#define LED_BUILTIN PNUM_NOT_DEFINED
|
||||
#endif
|
||||
|
||||
// On-board user button
|
||||
#ifndef USER_BTN
|
||||
#define USER_BTN PNUM_NOT_DEFINED
|
||||
#endif
|
||||
|
||||
// SPI definitions
|
||||
#ifndef PIN_SPI_SS
|
||||
#define PIN_SPI_SS PA4
|
||||
#endif
|
||||
#ifndef PIN_SPI_SS1
|
||||
#define PIN_SPI_SS1 PA15
|
||||
#endif
|
||||
#ifndef PIN_SPI_SS2
|
||||
#define PIN_SPI_SS2 PNUM_NOT_DEFINED
|
||||
#endif
|
||||
#ifndef PIN_SPI_SS3
|
||||
#define PIN_SPI_SS3 PNUM_NOT_DEFINED
|
||||
#endif
|
||||
#ifndef PIN_SPI_MOSI
|
||||
#define PIN_SPI_MOSI PA7
|
||||
#endif
|
||||
#ifndef PIN_SPI_MISO
|
||||
#define PIN_SPI_MISO PA6
|
||||
#endif
|
||||
#ifndef PIN_SPI_SCK
|
||||
#define PIN_SPI_SCK PA5
|
||||
#endif
|
||||
|
||||
// I2C definitions
|
||||
#ifndef PIN_WIRE_SDA
|
||||
#define PIN_WIRE_SDA PB7
|
||||
#endif
|
||||
#ifndef PIN_WIRE_SCL
|
||||
#define PIN_WIRE_SCL PB6
|
||||
#endif
|
||||
|
||||
// Timer Definitions
|
||||
// Use TIM6/TIM7 when possible as servo and tone don't need GPIO output pin
|
||||
#ifndef TIMER_TONE
|
||||
#define TIMER_TONE TIM6
|
||||
#endif
|
||||
#ifndef TIMER_SERVO
|
||||
#define TIMER_SERVO TIM21
|
||||
#endif
|
||||
|
||||
// UART Definitions
|
||||
#ifndef SERIAL_UART_INSTANCE
|
||||
#define SERIAL_UART_INSTANCE 2
|
||||
#endif
|
||||
|
||||
// Default pin used for generic 'Serial' instance
|
||||
// Mandatory for Firmata
|
||||
#ifndef PIN_SERIAL_RX
|
||||
#define PIN_SERIAL_RX PA3
|
||||
#endif
|
||||
#ifndef PIN_SERIAL_TX
|
||||
#define PIN_SERIAL_TX PA2
|
||||
#endif
|
||||
|
||||
// Extra HAL modules
|
||||
#if !defined(HAL_DAC_MODULE_DISABLED)
|
||||
#define HAL_DAC_MODULE_ENABLED
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
// These serial port names are intended to allow libraries and architecture-neutral
|
||||
// sketches to automatically default to the correct port name for a particular type
|
||||
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
|
||||
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
|
||||
//
|
||||
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
|
||||
//
|
||||
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
|
||||
//
|
||||
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
|
||||
// pins are NOT connected to anything by default.
|
||||
#ifndef SERIAL_PORT_MONITOR
|
||||
#define SERIAL_PORT_MONITOR Serial
|
||||
#endif
|
||||
#ifndef SERIAL_PORT_HARDWARE
|
||||
// KH mod to add Serial1, for ESP-AT
|
||||
//#define SERIAL_PORT_HARDWARE Serial
|
||||
#define SERIAL_PORT_HARDWARE Serial1
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,519 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_hal_conf_default.h
|
||||
* @brief HAL default configuration file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F4xx_HAL_CONF_DEFAULT_H
|
||||
#define __STM32F4xx_HAL_CONF_DEFAULT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief Include the default list of modules to be used in the HAL driver
|
||||
* and manage module deactivation
|
||||
*/
|
||||
#include "stm32yyxx_hal_conf.h"
|
||||
#if 0
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
#define HAL_MODULE_ENABLED
|
||||
#define HAL_ADC_MODULE_ENABLED
|
||||
#define HAL_CAN_MODULE_ENABLED
|
||||
/*#define HAL_CAN_LEGACY_MODULE_ENABLED*/
|
||||
#define HAL_CRC_MODULE_ENABLED
|
||||
#define HAL_CEC_MODULE_ENABLED
|
||||
#define HAL_CRYP_MODULE_ENABLED
|
||||
#define HAL_DAC_MODULE_ENABLED
|
||||
#define HAL_DCMI_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_DMA2D_MODULE_ENABLED
|
||||
#define HAL_ETH_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_NAND_MODULE_ENABLED
|
||||
#define HAL_NOR_MODULE_ENABLED
|
||||
#define HAL_PCCARD_MODULE_ENABLED
|
||||
#define HAL_SRAM_MODULE_ENABLED
|
||||
#define HAL_SDRAM_MODULE_ENABLED
|
||||
#define HAL_HASH_MODULE_ENABLED
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
#define HAL_SMBUS_MODULE_ENABLED
|
||||
#define HAL_I2S_MODULE_ENABLED
|
||||
#define HAL_IWDG_MODULE_ENABLED
|
||||
#define HAL_LTDC_MODULE_ENABLED
|
||||
#define HAL_DSI_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_QSPI_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
#define HAL_RNG_MODULE_ENABLED
|
||||
#define HAL_RTC_MODULE_ENABLED
|
||||
#define HAL_SAI_MODULE_ENABLED
|
||||
#define HAL_SD_MODULE_ENABLED
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
#define HAL_USART_MODULE_ENABLED
|
||||
#define HAL_IRDA_MODULE_ENABLED
|
||||
#define HAL_SMARTCARD_MODULE_ENABLED
|
||||
#define HAL_WWDG_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
#define HAL_PCD_MODULE_ENABLED
|
||||
#define HAL_HCD_MODULE_ENABLED
|
||||
#define HAL_FMPI2C_MODULE_ENABLED
|
||||
#define HAL_FMPSMBUS_MODULE_ENABLED
|
||||
#define HAL_SPDIFRX_MODULE_ENABLED
|
||||
#define HAL_DFSDM_MODULE_ENABLED
|
||||
#define HAL_LPTIM_MODULE_ENABLED
|
||||
#define HAL_MMC_MODULE_ENABLED
|
||||
#endif
|
||||
|
||||
/* ########################## HSE/HSI Values adaptation ##################### */
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSE is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI) value.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSI is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE 32000U /*!< LSI Typical Value in Hz */
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature. */
|
||||
/**
|
||||
* @brief External Low Speed oscillator (LSE) value.
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief External clock source for I2S peripheral
|
||||
* This value is used by the I2S HAL module to compute the I2S clock source
|
||||
* frequency, this source is inserted directly through I2S_CKIN pad.
|
||||
*/
|
||||
#if !defined (EXTERNAL_CLOCK_VALUE)
|
||||
#define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the External oscillator in Hz*/
|
||||
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
#if !defined (VDD_VALUE)
|
||||
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
|
||||
#endif
|
||||
#if !defined (TICK_INT_PRIORITY)
|
||||
#define TICK_INT_PRIORITY 0x00U /*!< tick interrupt priority */
|
||||
#endif
|
||||
#if !defined (USE_RTOS)
|
||||
#define USE_RTOS 0U
|
||||
#endif
|
||||
#if !defined (PREFETCH_ENABLE)
|
||||
#define PREFETCH_ENABLE 1U
|
||||
#endif
|
||||
#if !defined (INSTRUCTION_CACHE_ENABLE)
|
||||
#define INSTRUCTION_CACHE_ENABLE 1U
|
||||
#endif
|
||||
#if !defined (DATA_CACHE_ENABLE)
|
||||
#define DATA_CACHE_ENABLE 1U
|
||||
#endif
|
||||
|
||||
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
|
||||
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
|
||||
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
|
||||
#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */
|
||||
#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */
|
||||
#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */
|
||||
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
|
||||
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||
#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */
|
||||
#define USE_HAL_FMPSMBUS_REGISTER_CALLBACKS 0U /* FMPSMBUS register callback disabled */
|
||||
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
|
||||
#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */
|
||||
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||
#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */
|
||||
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */
|
||||
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
|
||||
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
|
||||
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
|
||||
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
|
||||
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1U */
|
||||
|
||||
/* ################## Ethernet peripheral configuration ##################### */
|
||||
|
||||
/* Section 1 : Ethernet peripheral configuration */
|
||||
|
||||
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||
#define MAC_ADDR0 2U
|
||||
#define MAC_ADDR1 0U
|
||||
#define MAC_ADDR2 0U
|
||||
#define MAC_ADDR3 0U
|
||||
#define MAC_ADDR4 0U
|
||||
#define MAC_ADDR5 0U
|
||||
|
||||
/* Definition of the Ethernet driver buffers size and count */
|
||||
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||
#define ETH_RXBUFNB (5U) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||
#define ETH_TXBUFNB (5U) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||
|
||||
/* Section 2: PHY configuration section */
|
||||
/* LAN8742A PHY Address*/
|
||||
////////////////////////////////
|
||||
//#define LAN8742A_PHY_ADDRESS 0x00U
|
||||
/* Section 2: PHY configuration section */
|
||||
#if !defined (LAN8742A_PHY_ADDRESS)
|
||||
/* KH, LAN8742A PHY Address*/
|
||||
#define LAN8742A_PHY_ADDRESS 0x00U
|
||||
#endif
|
||||
////////////////////////////////
|
||||
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||
#define PHY_RESET_DELAY 0x000000FFU
|
||||
/* PHY Configuration delay */
|
||||
#define PHY_CONFIG_DELAY 0x00000FFFU
|
||||
|
||||
#define PHY_READ_TO 0x0000FFFFU
|
||||
#define PHY_WRITE_TO 0x0000FFFFU
|
||||
|
||||
/* Section 3: Common PHY Registers */
|
||||
|
||||
#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */
|
||||
#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */
|
||||
|
||||
#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
|
||||
#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
|
||||
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
|
||||
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
|
||||
#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
|
||||
#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
|
||||
|
||||
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
|
||||
#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
|
||||
#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
|
||||
|
||||
/* Section 4: Extended PHY Registers */
|
||||
|
||||
#define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */
|
||||
|
||||
#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */
|
||||
#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */
|
||||
|
||||
|
||||
#define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */
|
||||
#define PHY_IMR ((uint16_t)0x1E) /*!< PHY Interrupt Mask register Offset */
|
||||
#define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */
|
||||
|
||||
/* ################## SPI peripheral configuration ########################## */
|
||||
|
||||
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||
* Activated: CRC code is present inside driver
|
||||
* Deactivated: CRC code cleaned from driver
|
||||
*/
|
||||
#if !defined (USE_SPI_CRC)
|
||||
#define USE_SPI_CRC 0U
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_can.h"
|
||||
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_can_legacy.h"
|
||||
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_cryp.h"
|
||||
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA2D_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dma2d.h"
|
||||
#endif /* HAL_DMA2D_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DCMI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dcmi.h"
|
||||
#endif /* HAL_DCMI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ETH_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_eth.h"
|
||||
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sram.h"
|
||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NOR_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_nor.h"
|
||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NAND_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_nand.h"
|
||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCCARD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_pccard.h"
|
||||
#endif /* HAL_PCCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SDRAM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sdram.h"
|
||||
#endif /* HAL_SDRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HASH_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_hash.h"
|
||||
#endif /* HAL_HASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMBUS_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_smbus.h"
|
||||
#endif /* HAL_SMBUS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LTDC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_ltdc.h"
|
||||
#endif /* HAL_LTDC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RNG_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_rng.h"
|
||||
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SAI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sai.h"
|
||||
#endif /* HAL_SAI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sd.h"
|
||||
#endif /* HAL_SD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_hcd.h"
|
||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DSI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dsi.h"
|
||||
#endif /* HAL_DSI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_QSPI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_qspi.h"
|
||||
#endif /* HAL_QSPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CEC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_cec.h"
|
||||
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FMPI2C_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_fmpi2c.h"
|
||||
#endif /* HAL_FMPI2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FMPSMBUS_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_fmpsmbus.h"
|
||||
#endif /* HAL_FMPSMBUS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPDIFRX_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_spdifrx.h"
|
||||
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DFSDM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dfsdm.h"
|
||||
#endif /* HAL_DFSDM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_lptim.h"
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MMC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_mmc.h"
|
||||
#endif /* HAL_MMC_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t *file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F4xx_HAL_CONF_DEFAULT_H */
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,511 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f7xx_hal_conf_default.h
|
||||
* @brief HAL default configuration file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F7xx_HAL_CONF_DEFAULT_H
|
||||
#define __STM32F7xx_HAL_CONF_DEFAULT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief Include the default list of modules to be used in the HAL driver
|
||||
* and manage module deactivation
|
||||
*/
|
||||
#include "stm32yyxx_hal_conf.h"
|
||||
#if 0
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
#define HAL_MODULE_ENABLED
|
||||
#define HAL_ADC_MODULE_ENABLED
|
||||
#define HAL_CAN_MODULE_ENABLED
|
||||
#define HAL_CAN_LEGACY_MODULE_ENABLED
|
||||
#define HAL_CEC_MODULE_ENABLED
|
||||
#define HAL_CRC_MODULE_ENABLED
|
||||
#define HAL_CRYP_MODULE_ENABLED
|
||||
#define HAL_DAC_MODULE_ENABLED
|
||||
#define HAL_DCMI_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_DMA2D_MODULE_ENABLED
|
||||
#define HAL_ETH_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_NAND_MODULE_ENABLED
|
||||
#define HAL_NOR_MODULE_ENABLED
|
||||
#define HAL_SRAM_MODULE_ENABLED
|
||||
#define HAL_SDRAM_MODULE_ENABLED
|
||||
#define HAL_HASH_MODULE_ENABLED
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
#define HAL_I2S_MODULE_ENABLED
|
||||
#define HAL_IWDG_MODULE_ENABLED
|
||||
#define HAL_LPTIM_MODULE_ENABLED
|
||||
#define HAL_LTDC_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_QSPI_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
#define HAL_RNG_MODULE_ENABLED
|
||||
#define HAL_RTC_MODULE_ENABLED
|
||||
#define HAL_SAI_MODULE_ENABLED
|
||||
#define HAL_SD_MODULE_ENABLED
|
||||
#define HAL_SPDIFRX_MODULE_ENABLED
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
#define HAL_USART_MODULE_ENABLED
|
||||
#define HAL_IRDA_MODULE_ENABLED
|
||||
#define HAL_SMARTCARD_MODULE_ENABLED
|
||||
#define HAL_WWDG_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
#define HAL_PCD_MODULE_ENABLED
|
||||
#define HAL_HCD_MODULE_ENABLED
|
||||
#define HAL_DFSDM_MODULE_ENABLED
|
||||
#define HAL_DSI_MODULE_ENABLED
|
||||
#define HAL_JPEG_MODULE_ENABLED
|
||||
#define HAL_MDIOS_MODULE_ENABLED
|
||||
#define HAL_SMBUS_MODULE_ENABLED
|
||||
#define HAL_MMC_MODULE_ENABLED
|
||||
#endif
|
||||
|
||||
/* ########################## HSE/HSI Values adaptation ##################### */
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSE is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI) value.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSI is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature. */
|
||||
/**
|
||||
* @brief External Low Speed oscillator (LSE) value.
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief External clock source for I2S peripheral
|
||||
* This value is used by the I2S HAL module to compute the I2S clock source
|
||||
* frequency, this source is inserted directly through I2S_CKIN pad.
|
||||
*/
|
||||
#if !defined (EXTERNAL_CLOCK_VALUE)
|
||||
#define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
#if !defined (VDD_VALUE)
|
||||
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
|
||||
#endif
|
||||
#if !defined (TICK_INT_PRIORITY)
|
||||
#define TICK_INT_PRIORITY 0x00U /*!< tick interrupt priority */
|
||||
#endif
|
||||
#if !defined (USE_RTOS)
|
||||
#define USE_RTOS 0U
|
||||
#endif
|
||||
#if !defined (PREFETCH_ENABLE)
|
||||
#define PREFETCH_ENABLE 1U /* To enable prefetch */
|
||||
#endif
|
||||
#if !defined (ART_ACCLERATOR_ENABLE)
|
||||
#define ART_ACCLERATOR_ENABLE 1U /* To enable ART Accelerator */
|
||||
#endif
|
||||
|
||||
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
|
||||
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
|
||||
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
|
||||
#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */
|
||||
#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */
|
||||
#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */
|
||||
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
|
||||
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||
#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */
|
||||
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
|
||||
#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */
|
||||
#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIOS register callback disabled */
|
||||
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */
|
||||
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
|
||||
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
|
||||
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
|
||||
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
|
||||
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1 */
|
||||
|
||||
/* ################## Ethernet peripheral configuration ##################### */
|
||||
|
||||
/* Section 1 : Ethernet peripheral configuration */
|
||||
|
||||
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||
#define MAC_ADDR0 2U
|
||||
#define MAC_ADDR1 0U
|
||||
#define MAC_ADDR2 0U
|
||||
#define MAC_ADDR3 0U
|
||||
#define MAC_ADDR4 0U
|
||||
#define MAC_ADDR5 0U
|
||||
|
||||
/* Definition of the Ethernet driver buffers size and count */
|
||||
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||
#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||
#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||
|
||||
/* Section 2: PHY configuration section */
|
||||
/* LAN8742A PHY Address*/
|
||||
////////////////////////////////
|
||||
//#define LAN8742A_PHY_ADDRESS 0x00U
|
||||
/* Section 2: PHY configuration section */
|
||||
#if !defined (LAN8742A_PHY_ADDRESS)
|
||||
/* KH, LAN8742A PHY Address*/
|
||||
#define LAN8742A_PHY_ADDRESS 0x00U
|
||||
#endif
|
||||
////////////////////////////////
|
||||
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||
#define PHY_RESET_DELAY 0x00000FFFU
|
||||
/* PHY Configuration delay */
|
||||
#define PHY_CONFIG_DELAY 0x00000FFFU
|
||||
|
||||
#define PHY_READ_TO 0x0000FFFFU
|
||||
#define PHY_WRITE_TO 0x0000FFFFU
|
||||
|
||||
/* Section 3: Common PHY Registers */
|
||||
|
||||
#define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */
|
||||
#define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */
|
||||
|
||||
#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
|
||||
#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
|
||||
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
|
||||
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
|
||||
#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
|
||||
#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
|
||||
|
||||
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
|
||||
#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
|
||||
#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
|
||||
|
||||
/* Section 4: Extended PHY Registers */
|
||||
|
||||
#define PHY_SR ((uint16_t)0x1FU) /*!< PHY special control/ status register Offset */
|
||||
|
||||
#define PHY_SPEED_STATUS ((uint16_t)0x0004U) /*!< PHY Speed mask */
|
||||
#define PHY_DUPLEX_STATUS ((uint16_t)0x0010U) /*!< PHY Duplex mask */
|
||||
|
||||
|
||||
#define PHY_ISFR ((uint16_t)0x01DU) /*!< PHY Interrupt Source Flag register Offset */
|
||||
#define PHY_IMR ((uint16_t)0x001E) /*!< PHY Interrupt Mask register Offset */
|
||||
#define PHY_ISFR_INT4 ((uint16_t)0x0010U) /*!< PHY Link down inturrupt */
|
||||
|
||||
/* ################## SPI peripheral configuration ########################## */
|
||||
|
||||
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||
* Activated: CRC code is present inside driver
|
||||
* Deactivated: CRC code cleaned from driver
|
||||
*/
|
||||
#if !defined (USE_SPI_CRC)
|
||||
#define USE_SPI_CRC 0U
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_can.h"
|
||||
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_can_legacy.h"
|
||||
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CEC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_cec.h"
|
||||
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_cryp.h"
|
||||
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA2D_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dma2d.h"
|
||||
#endif /* HAL_DMA2D_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DCMI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dcmi.h"
|
||||
#endif /* HAL_DCMI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ETH_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_eth.h"
|
||||
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sram.h"
|
||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NOR_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_nor.h"
|
||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NAND_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_nand.h"
|
||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SDRAM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sdram.h"
|
||||
#endif /* HAL_SDRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HASH_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_hash.h"
|
||||
#endif /* HAL_HASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_lptim.h"
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LTDC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_ltdc.h"
|
||||
#endif /* HAL_LTDC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_QSPI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_qspi.h"
|
||||
#endif /* HAL_QSPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RNG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_rng.h"
|
||||
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SAI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sai.h"
|
||||
#endif /* HAL_SAI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sd.h"
|
||||
#endif /* HAL_SD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPDIFRX_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_spdifrx.h"
|
||||
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_hcd.h"
|
||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DFSDM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dfsdm.h"
|
||||
#endif /* HAL_DFSDM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DSI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dsi.h"
|
||||
#endif /* HAL_DSI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_JPEG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_jpeg.h"
|
||||
#endif /* HAL_JPEG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MDIOS_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_mdios.h"
|
||||
#endif /* HAL_MDIOS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMBUS_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_smbus.h"
|
||||
#endif /* HAL_SMBUS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MMC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_mmc.h"
|
||||
#endif /* HAL_MMC_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t *file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F7xx_HAL_CONF_DEFAULT_H */
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user