Minor header/directrory cleanup (#802)

This commit is contained in:
Earle F. Philhower, III 2022-08-27 13:04:57 -07:00 committed by GitHub
parent 257db5ac7d
commit 064dd4794f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 1226 additions and 1116 deletions

View file

@ -71,8 +71,6 @@ static int __usb_task_irq;
#define EPNUM_HID 0x83
#define EPNUM_MIDI 0x01
const uint8_t *tud_descriptor_device_cb(void) {
static tusb_desc_device_t usbd_desc_device = {
@ -91,7 +89,7 @@ const uint8_t *tud_descriptor_device_cb(void) {
.iSerialNumber = USBD_STR_SERIAL,
.bNumConfigurations = 1
};
if (__USBInstallSerial && !__USBInstallKeyboard && !__USBInstallMouse && !__USBInstallJoystick && !__USBInstallMIDI) {
if (__USBInstallSerial && !__USBInstallKeyboard && !__USBInstallMouse && !__USBInstallJoystick) {
// Can use as-is, this is the default USB case
return (const uint8_t *)&usbd_desc_device;
}
@ -105,9 +103,6 @@ const uint8_t *tud_descriptor_device_cb(void) {
if (__USBInstallJoystick) {
usbd_desc_device.idProduct |= 0x0100;
}
if (__USBInstallMIDI) {
usbd_desc_device.idProduct |= 0x2000;
}
// Set the device class to 0 to indicate multiple device classes
usbd_desc_device.bDeviceClass = 0;
usbd_desc_device.bDeviceSubClass = 0;
@ -228,7 +223,7 @@ void __SetupUSBDescriptor() {
if (!usbd_desc_cfg) {
bool hasHID = __USBInstallKeyboard || __USBInstallMouse || __USBInstallJoystick;
uint8_t interface_count = (__USBInstallSerial ? 2 : 0) + (hasHID ? 1 : 0) + (__USBInstallMIDI ? 2 : 0);
uint8_t interface_count = (__USBInstallSerial ? 2 : 0) + (hasHID ? 1 : 0);
uint8_t cdc_desc[TUD_CDC_DESC_LEN] = {
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
@ -243,13 +238,7 @@ void __SetupUSBDescriptor() {
TUD_HID_DESCRIPTOR(hid_itf, 0, HID_ITF_PROTOCOL_NONE, hid_report_len, EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10)
};
uint8_t midi_itf = hid_itf + (hasHID ? 1 : 0);
uint8_t midi_desc[TUD_MIDI_DESC_LEN] = {
// Interface number, string index, EP Out & EP In address, EP size
TUD_MIDI_DESCRIPTOR(midi_itf, 0, EPNUM_MIDI, 0x80 | EPNUM_MIDI, 64)
};
int usbd_desc_len = TUD_CONFIG_DESC_LEN + (__USBInstallSerial ? sizeof(cdc_desc) : 0) + (hasHID ? sizeof(hid_desc) : 0) + (__USBInstallMIDI ? sizeof(midi_desc) : 0);
int usbd_desc_len = TUD_CONFIG_DESC_LEN + (__USBInstallSerial ? sizeof(cdc_desc) : 0) + (hasHID ? sizeof(hid_desc) : 0);
uint8_t tud_cfg_desc[TUD_CONFIG_DESC_LEN] = {
// Config number, interface count, string index, total length, attribute, power in mA
@ -271,9 +260,6 @@ void __SetupUSBDescriptor() {
memcpy(ptr, hid_desc, sizeof(hid_desc));
ptr += sizeof(hid_desc);
}
if (__USBInstallMIDI) {
memcpy(ptr, midi_desc, sizeof(midi_desc));
}
}
}
}

View file

@ -26,7 +26,6 @@ extern void __USBInstallSerial() __attribute__((weak));
extern void __USBInstallKeyboard() __attribute__((weak));
extern void __USBInstallJoystick() __attribute__((weak));
extern void __USBInstallMouse() __attribute__((weak));
extern void __USBInstallMIDI() __attribute__((weak));
// Big, global USB mutex, shared with all USB devices to make sure we don't
// have multiple cores updating the TUSB state in parallel

View file

@ -1,3 +1,24 @@
/*
Arduino OTA.cpp - Simple Arduino IDE OTA handler
Modified 2022 Earle F. Philhower, III. All rights reserved.
Taken from the ESP8266 core libraries, (c) various authors.
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
*/
#include <functional>
#include <WiFiUdp.h>
#include "ArduinoOTA.h"

View file

@ -1,3 +1,24 @@
/*
Arduino OTA.h - Simple Arduino IDE OTA handler
Modified 2022 Earle F. Philhower, III. All rights reserved.
Taken from the ESP8266 core libraries, (c) various authors.
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
*/
#pragma once
#include <WiFi.h>

View file

@ -133,7 +133,9 @@ void loop() {
WiFi.disconnect();
}
}
if (s == WL_CONNECTED) { MDNS.update(); }
if (s == WL_CONNECTED) {
MDNS.update();
}
}
// Do work:
// DNS

View file

@ -57,21 +57,23 @@ void handleWifi() {
+ String(softAP_ssid) + F("</td></tr>"
"<tr><td>IP ")
+ toStringIp(WiFi.softAPIP()) + F("</td></tr>"
"</table>"
"\r\n<br />"
"<table><tr><th align='left'>WLAN config</th></tr>"
"<tr><td>SSID ")
"</table>"
"\r\n<br />"
"<table><tr><th align='left'>WLAN config</th></tr>"
"<tr><td>SSID ")
+ String(ssid) + F("</td></tr>"
"<tr><td>IP ")
+ toStringIp(WiFi.localIP()) + F("</td></tr>"
"</table>"
"\r\n<br />"
"<table><tr><th align='left'>WLAN list (refresh if any missing)</th></tr>");
"</table>"
"\r\n<br />"
"<table><tr><th align='left'>WLAN list (refresh if any missing)</th></tr>");
Serial.println("scan start");
int n = WiFi.scanNetworks();
Serial.println("scan done");
if (n > 0) {
for (int i = 0; i < n; i++) { Page += String(F("\r\n<tr><td>SSID ")) + WiFi.SSID(i) + ((WiFi.encryptionType(i) == ENC_TYPE_NONE) ? F(" ") : F(" *")) + F(" (") + WiFi.RSSI(i) + F(")</td></tr>"); }
for (int i = 0; i < n; i++) {
Page += String(F("\r\n<tr><td>SSID ")) + WiFi.SSID(i) + ((WiFi.encryptionType(i) == ENC_TYPE_NONE) ? F(" ") : F(" *")) + F(" (") + WiFi.RSSI(i) + F(")</td></tr>");
}
} else {
Page += F("<tr><td>No WLAN found</td></tr>");
}
@ -114,7 +116,9 @@ void handleNotFound() {
message += server.args();
message += F("\n");
for (uint8_t i = 0; i < server.args(); i++) { message += String(F(" ")) + server.argName(i) + F(": ") + server.arg(i) + F("\n"); }
for (uint8_t i = 0; i < server.args(); i++) {
message += String(F(" ")) + server.argName(i) + F(": ") + server.arg(i) + F("\n");
}
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server.sendHeader("Pragma", "no-cache");
server.sendHeader("Expires", "-1");

View file

@ -2,7 +2,9 @@
boolean isIp(String str) {
for (size_t i = 0; i < str.length(); i++) {
int c = str.charAt(i);
if (c != '.' && (c < '0' || c > '9')) { return false; }
if (c != '.' && (c < '0' || c > '9')) {
return false;
}
}
return true;
}
@ -10,7 +12,9 @@ boolean isIp(String str) {
/** IP to String? */
String toStringIp(IPAddress ip) {
String res = "";
for (int i = 0; i < 3; i++) { res += String((ip >> (8 * i)) & 0xFF) + "."; }
for (int i = 0; i < 3; i++) {
res += String((ip >> (8 * i)) & 0xFF) + ".";
}
res += String(((ip >> 8 * 3)) & 0xFF);
return res;
}

View file

@ -1,10 +1,29 @@
/*
DNSServer.cpp - Simple DNS server for the Pico
Modified 2022 Earle F. Philhower, III. All rights reserved.
Taken from the ESP8266 core libraries, (c) various authors.
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
*/
#include "WiFi.h"
#include "DNSServer.h"
#include <lwip/def.h>
#include <Arduino.h>
extern struct rst_info resetInfo;
#ifdef DEBUG_ESP_PORT
#define CONSOLE DEBUG_ESP_PORT
#else
@ -49,399 +68,389 @@ extern struct rst_info resetInfo;
// Want to keep IDs unique across restarts and continquious
static uint32_t _ids __attribute__((section(".noinit")));
DNSServer::DNSServer()
{
// I have observed that using 0 for captive and non-zero (600) when
// forwarding, will help Android devices recognize the change in connectivity.
// They will then report connected.
_ttl = lwip_htonl(60);
DNSServer::DNSServer() {
// I have observed that using 0 for captive and non-zero (600) when
// forwarding, will help Android devices recognize the change in connectivity.
// They will then report connected.
_ttl = lwip_htonl(60);
srand(rp2040.getCycleCount());
_ids = random(0, (1UL << 16) - 1);
srand(rp2040.getCycleCount());
_ids = random(0, (1UL << 16) - 1);
_errorReplyCode = DNSReplyCode::NonExistentDomain;
_errorReplyCode = DNSReplyCode::NonExistentDomain;
}
void DNSServer::disableForwarder(const String &domainName, bool freeResources)
{
_forwarder = false;
if (domainName != "") {
_domainName = domainName;
downcaseAndRemoveWwwPrefix(_domainName);
}
if (freeResources) {
_dns = (uint32_t)0;
if (_que) {
_que = nullptr;
DEBUG_PRINTF("from stop, deleted _que\r\n");
DEBUG_(({
if (_que_ov) {
DEBUG_PRINTLN2("DNS forwarder que overflow or no reply to request: ", (_que_ov));
}
if (_que_drop) {
DEBUG_PRINTLN2("DNS forwarder que wrapped, reply dropped: ", (_que_drop));
}
}));
void DNSServer::disableForwarder(const String &domainName, bool freeResources) {
_forwarder = false;
if (domainName != "") {
_domainName = domainName;
downcaseAndRemoveWwwPrefix(_domainName);
}
if (freeResources) {
_dns = (uint32_t)0;
if (_que) {
_que = nullptr;
DEBUG_PRINTF("from stop, deleted _que\r\n");
DEBUG_(({
if (_que_ov) {
DEBUG_PRINTLN2("DNS forwarder que overflow or no reply to request: ", (_que_ov));
}
if (_que_drop) {
DEBUG_PRINTLN2("DNS forwarder que wrapped, reply dropped: ", (_que_drop));
}
}));
}
}
}
}
bool DNSServer::enableForwarder(const String &domainName, const IPAddress &dns)
{
disableForwarder(domainName, false); // Just happens to have the same logic needed here.
bool DNSServer::enableForwarder(const String &domainName, const IPAddress &dns) {
disableForwarder(domainName, false); // Just happens to have the same logic needed here.
if (dns.isSet()) {
_dns = dns;
}
if (dns.isSet()) {
_dns = dns;
}
if (_dns.isSet()) {
if (!_que) {
_que = std::unique_ptr<DNSS_REQUESTER[]> (new (std::nothrow) DNSS_REQUESTER[kDNSSQueSize]);
DEBUG_PRINTF("Created new _que\r\n");
if (_que) {
for (size_t i = 0; i < kDNSSQueSize; i++) {
_que[i].ip = 0;
if (_dns.isSet()) {
if (!_que) {
_que = std::unique_ptr<DNSS_REQUESTER[]> (new (std::nothrow) DNSS_REQUESTER[kDNSSQueSize]);
DEBUG_PRINTF("Created new _que\r\n");
if (_que) {
for (size_t i = 0; i < kDNSSQueSize; i++) {
_que[i].ip = 0;
}
DEBUG_((_que_ov = 0));
DEBUG_((_que_drop = 0));
}
}
if (_que) {
_forwarder = true;
}
DEBUG_((_que_ov = 0));
DEBUG_((_que_drop = 0));
}
}
if (_que) {
_forwarder = true;
}
}
return _forwarder;
return _forwarder;
}
bool DNSServer::start(const uint16_t &port, const String &domainName,
const IPAddress &resolvedIP, const IPAddress &dns)
{
_port = (port) ? port : IANA_DNS_PORT;
const IPAddress &resolvedIP, const IPAddress &dns) {
_port = (port) ? port : IANA_DNS_PORT;
_resolvedIP[0] = resolvedIP[0];
_resolvedIP[1] = resolvedIP[1];
_resolvedIP[2] = resolvedIP[2];
_resolvedIP[3] = resolvedIP[3];
_resolvedIP[0] = resolvedIP[0];
_resolvedIP[1] = resolvedIP[1];
_resolvedIP[2] = resolvedIP[2];
_resolvedIP[3] = resolvedIP[3];
if (!enableForwarder(domainName, dns) && (dns.isSet() || _dns.isSet())) {
return false;
}
return _udp.begin(_port) == 1;
}
void DNSServer::setErrorReplyCode(const DNSReplyCode &replyCode)
{
_errorReplyCode = replyCode;
}
void DNSServer::setTTL(const uint32_t &ttl)
{
_ttl = lwip_htonl(ttl);
}
uint32_t DNSServer::getTTL()
{
return lwip_ntohl(_ttl);
}
void DNSServer::stop()
{
_udp.stop();
disableForwarder("", true);
}
void DNSServer::downcaseAndRemoveWwwPrefix(String &domainName)
{
domainName.toLowerCase();
if (domainName.startsWith("www."))
domainName.remove(0, 4);
}
void DNSServer::forwardReply(uint8_t *buffer, size_t length)
{
if (!_forwarder || !_que) {
return;
}
DNSHeader *dnsHeader = (DNSHeader *)buffer;
uint16_t id = dnsHeader->ID;
// if (kDNSSQueSize <= (uint16_t)((uint16_t)_ids - id)) {
if ((uint16_t)kDNSSQueSize <= (uint16_t)_ids - id) {
DEBUG_((++_que_drop));
DEBUG_PRINTLN2("Forward reply ID: 0x", (String(id, HEX) + F(" dropped!")));
return;
}
size_t i = id & (kDNSSQueSize - 1);
// Drop duplicate packets
if (0 == _que[i].ip) {
DEBUG_PRINTLN2("Duplicate reply dropped ID: 0x", String(id, HEX));
return;
}
dnsHeader->ID = _que[i].id;
_udp.beginPacket(_que[i].ip, _que[i].port);
_udp.write(buffer, length);
_udp.endPacket();
DEBUG_PRINTLN2("Forward reply ID: 0x", (String(id, HEX) + F(" to ") + IPAddress(_que[i].ip).toString()));
_que[i].ip = 0; // This gets used to detect duplicate packets and overflow
}
void DNSServer::forwardRequest(uint8_t *buffer, size_t length)
{
if (!_forwarder || !_dns.isSet() || !_que) {
return;
}
DNSHeader *dnsHeader = (DNSHeader *)buffer;
++_ids;
size_t i = _ids & (kDNSSQueSize - 1);
DEBUG_(({
if (0 != _que[i].ip) {
++_que_ov;
if (!enableForwarder(domainName, dns) && (dns.isSet() || _dns.isSet())) {
return false;
}
}));
_que[i].ip = _udp.remoteIP();
_que[i].port = _udp.remotePort();
_que[i].id = dnsHeader->ID;
dnsHeader->ID = (uint16_t)_ids;
_udp.beginPacket(_dns, IANA_DNS_PORT);
_udp.write(buffer, length);
_udp.endPacket();
DEBUG_PRINTLN2("Forward request ID: 0x", (String(dnsHeader->ID, HEX) + F(" to ") + _dns.toString()));
return _udp.begin(_port) == 1;
}
bool DNSServer::respondToRequest(uint8_t *buffer, size_t length)
{
DNSHeader *dnsHeader;
uint8_t *query, *start;
const char *matchString;
size_t remaining, labelLength, queryLength;
uint16_t qtype, qclass;
void DNSServer::setErrorReplyCode(const DNSReplyCode &replyCode) {
_errorReplyCode = replyCode;
}
dnsHeader = (DNSHeader *)buffer;
void DNSServer::setTTL(const uint32_t &ttl) {
_ttl = lwip_htonl(ttl);
}
// Must be a query for us to do anything with it
if (dnsHeader->QR != DNS_QR_QUERY) {
return false;
}
uint32_t DNSServer::getTTL() {
return lwip_ntohl(_ttl);
}
// If operation is anything other than query, we don't do it
if (dnsHeader->OPCode != DNS_OPCODE_QUERY) {
replyWithError(dnsHeader, DNSReplyCode::NotImplemented);
return false;
}
void DNSServer::stop() {
_udp.stop();
disableForwarder("", true);
}
// Only support requests containing single queries - everything else
// is badly defined
if (dnsHeader->QDCount != lwip_htons(1)) {
replyWithError(dnsHeader, DNSReplyCode::FormError);
return false;
}
// We must return a FormError in the case of a non-zero ARCount to
// be minimally compatible with EDNS resolvers
if (dnsHeader->ANCount != 0 || dnsHeader->NSCount != 0
|| dnsHeader->ARCount != 0) {
replyWithError(dnsHeader, DNSReplyCode::FormError);
return false;
}
// Even if we're not going to use the query, we need to parse it
// so we can check the address type that's being queried
query = start = buffer + DNS_HEADER_SIZE;
remaining = length - DNS_HEADER_SIZE;
while (remaining != 0 && *start != 0) {
labelLength = *start;
if (labelLength + 1 > remaining) {
replyWithError(dnsHeader, DNSReplyCode::FormError);
return false;
void DNSServer::downcaseAndRemoveWwwPrefix(String &domainName) {
domainName.toLowerCase();
if (domainName.startsWith("www.")) {
domainName.remove(0, 4);
}
remaining -= (labelLength + 1);
start += (labelLength + 1);
}
}
// 1 octet labelLength, 2 octet qtype, 2 octet qclass
if (remaining < 5) {
replyWithError(dnsHeader, DNSReplyCode::FormError);
return false;
}
start += 1; // Skip the 0 length label that we found above
memcpy(&qtype, start, sizeof(qtype));
start += 2;
memcpy(&qclass, start, sizeof(qclass));
start += 2;
queryLength = start - query;
if (qclass != lwip_htons(DNS_QCLASS_ANY)
&& qclass != lwip_htons(DNS_QCLASS_IN)) {
replyWithError(dnsHeader, DNSReplyCode::NonExistentDomain, query, queryLength);
return false;
}
if (qtype != lwip_htons(DNS_QTYPE_A)
&& qtype != lwip_htons(DNS_QTYPE_ANY)) {
replyWithError(dnsHeader, DNSReplyCode::NonExistentDomain, query, queryLength);
return false;
}
// If we have no domain name configured, just return an error
if (_domainName == "") {
if (_forwarder) {
return true;
} else {
replyWithError(dnsHeader, _errorReplyCode, query, queryLength);
return false;
void DNSServer::forwardReply(uint8_t *buffer, size_t length) {
if (!_forwarder || !_que) {
return;
}
}
DNSHeader *dnsHeader = (DNSHeader *)buffer;
uint16_t id = dnsHeader->ID;
// if (kDNSSQueSize <= (uint16_t)((uint16_t)_ids - id)) {
if ((uint16_t)kDNSSQueSize <= (uint16_t)_ids - id) {
DEBUG_((++_que_drop));
DEBUG_PRINTLN2("Forward reply ID: 0x", (String(id, HEX) + F(" dropped!")));
return;
}
size_t i = id & (kDNSSQueSize - 1);
// If we're running with a wildcard we can just return a result now
if (_domainName == "*") {
DEBUG_PRINTF("dnsServer - replyWithIP\r\n");
replyWithIP(dnsHeader, query, queryLength);
return false;
}
// Drop duplicate packets
if (0 == _que[i].ip) {
DEBUG_PRINTLN2("Duplicate reply dropped ID: 0x", String(id, HEX));
return;
}
dnsHeader->ID = _que[i].id;
_udp.beginPacket(_que[i].ip, _que[i].port);
_udp.write(buffer, length);
_udp.endPacket();
DEBUG_PRINTLN2("Forward reply ID: 0x", (String(id, HEX) + F(" to ") + IPAddress(_que[i].ip).toString()));
_que[i].ip = 0; // This gets used to detect duplicate packets and overflow
}
matchString = _domainName.c_str();
start = query;
// If there's a leading 'www', skip it
if (*start == 3 && strncasecmp("www", (char *) start + 1, 3) == 0)
start += 4;
while (*start != 0) {
labelLength = *start;
start += 1;
while (labelLength > 0) {
if (tolower(*start) != *matchString) {
if (_forwarder) {
return true;
} else {
replyWithError(dnsHeader, _errorReplyCode, query, queryLength);
return false;
void DNSServer::forwardRequest(uint8_t *buffer, size_t length) {
if (!_forwarder || !_dns.isSet() || !_que) {
return;
}
DNSHeader *dnsHeader = (DNSHeader *)buffer;
++_ids;
size_t i = _ids & (kDNSSQueSize - 1);
DEBUG_(({
if (0 != _que[i].ip) {
++_que_ov;
}
}
++start;
++matchString;
--labelLength;
}
if (*start == 0 && *matchString == '\0') {
replyWithIP(dnsHeader, query, queryLength);
return false;
}
if (*matchString != '.') {
replyWithError(dnsHeader, _errorReplyCode, query, queryLength);
return false;
}
++matchString;
}
replyWithError(dnsHeader, _errorReplyCode, query, queryLength);
return false;
}));
_que[i].ip = _udp.remoteIP();
_que[i].port = _udp.remotePort();
_que[i].id = dnsHeader->ID;
dnsHeader->ID = (uint16_t)_ids;
_udp.beginPacket(_dns, IANA_DNS_PORT);
_udp.write(buffer, length);
_udp.endPacket();
DEBUG_PRINTLN2("Forward request ID: 0x", (String(dnsHeader->ID, HEX) + F(" to ") + _dns.toString()));
}
void DNSServer::processNextRequest()
{
size_t currentPacketSize;
bool DNSServer::respondToRequest(uint8_t *buffer, size_t length) {
DNSHeader *dnsHeader;
uint8_t *query, *start;
const char *matchString;
size_t remaining, labelLength, queryLength;
uint16_t qtype, qclass;
currentPacketSize = _udp.parsePacket();
if (currentPacketSize == 0)
return;
dnsHeader = (DNSHeader *)buffer;
// The DNS RFC requires that DNS packets be less than 512 bytes in size,
// so just discard them if they are larger
if (currentPacketSize > MAX_DNS_PACKETSIZE)
return;
// Must be a query for us to do anything with it
if (dnsHeader->QR != DNS_QR_QUERY) {
return false;
}
// If the packet size is smaller than the DNS header, then someone is
// messing with us
if (currentPacketSize < DNS_HEADER_SIZE)
return;
// If operation is anything other than query, we don't do it
if (dnsHeader->OPCode != DNS_OPCODE_QUERY) {
replyWithError(dnsHeader, DNSReplyCode::NotImplemented);
return false;
}
std::unique_ptr<uint8_t[]> buffer(new (std::nothrow) uint8_t[currentPacketSize]);
if (buffer == nullptr)
return;
// Only support requests containing single queries - everything else
// is badly defined
if (dnsHeader->QDCount != lwip_htons(1)) {
replyWithError(dnsHeader, DNSReplyCode::FormError);
return false;
}
_udp.read(buffer.get(), currentPacketSize);
if (_dns.isSet() && _udp.remoteIP() == _dns) {
// _forwarder may have been set to false; however, for now allow in-flight
// replies to finish. //??
forwardReply(buffer.get(), currentPacketSize);
} else
if (respondToRequest(buffer.get(), currentPacketSize)) {
forwardRequest(buffer.get(), currentPacketSize);
}
// We must return a FormError in the case of a non-zero ARCount to
// be minimally compatible with EDNS resolvers
if (dnsHeader->ANCount != 0 || dnsHeader->NSCount != 0
|| dnsHeader->ARCount != 0) {
replyWithError(dnsHeader, DNSReplyCode::FormError);
return false;
}
// Even if we're not going to use the query, we need to parse it
// so we can check the address type that's being queried
query = start = buffer + DNS_HEADER_SIZE;
remaining = length - DNS_HEADER_SIZE;
while (remaining != 0 && *start != 0) {
labelLength = *start;
if (labelLength + 1 > remaining) {
replyWithError(dnsHeader, DNSReplyCode::FormError);
return false;
}
remaining -= (labelLength + 1);
start += (labelLength + 1);
}
// 1 octet labelLength, 2 octet qtype, 2 octet qclass
if (remaining < 5) {
replyWithError(dnsHeader, DNSReplyCode::FormError);
return false;
}
start += 1; // Skip the 0 length label that we found above
memcpy(&qtype, start, sizeof(qtype));
start += 2;
memcpy(&qclass, start, sizeof(qclass));
start += 2;
queryLength = start - query;
if (qclass != lwip_htons(DNS_QCLASS_ANY)
&& qclass != lwip_htons(DNS_QCLASS_IN)) {
replyWithError(dnsHeader, DNSReplyCode::NonExistentDomain, query, queryLength);
return false;
}
if (qtype != lwip_htons(DNS_QTYPE_A)
&& qtype != lwip_htons(DNS_QTYPE_ANY)) {
replyWithError(dnsHeader, DNSReplyCode::NonExistentDomain, query, queryLength);
return false;
}
// If we have no domain name configured, just return an error
if (_domainName == "") {
if (_forwarder) {
return true;
} else {
replyWithError(dnsHeader, _errorReplyCode, query, queryLength);
return false;
}
}
// If we're running with a wildcard we can just return a result now
if (_domainName == "*") {
DEBUG_PRINTF("dnsServer - replyWithIP\r\n");
replyWithIP(dnsHeader, query, queryLength);
return false;
}
matchString = _domainName.c_str();
start = query;
// If there's a leading 'www', skip it
if (*start == 3 && strncasecmp("www", (char *) start + 1, 3) == 0) {
start += 4;
}
while (*start != 0) {
labelLength = *start;
start += 1;
while (labelLength > 0) {
if (tolower(*start) != *matchString) {
if (_forwarder) {
return true;
} else {
replyWithError(dnsHeader, _errorReplyCode, query, queryLength);
return false;
}
}
++start;
++matchString;
--labelLength;
}
if (*start == 0 && *matchString == '\0') {
replyWithIP(dnsHeader, query, queryLength);
return false;
}
if (*matchString != '.') {
replyWithError(dnsHeader, _errorReplyCode, query, queryLength);
return false;
}
++matchString;
}
replyWithError(dnsHeader, _errorReplyCode, query, queryLength);
return false;
}
void DNSServer::writeNBOShort(uint16_t value)
{
_udp.write((unsigned char *)&value, 2);
void DNSServer::processNextRequest() {
size_t currentPacketSize;
currentPacketSize = _udp.parsePacket();
if (currentPacketSize == 0) {
return;
}
// The DNS RFC requires that DNS packets be less than 512 bytes in size,
// so just discard them if they are larger
if (currentPacketSize > MAX_DNS_PACKETSIZE) {
return;
}
// If the packet size is smaller than the DNS header, then someone is
// messing with us
if (currentPacketSize < DNS_HEADER_SIZE) {
return;
}
std::unique_ptr<uint8_t[]> buffer(new (std::nothrow) uint8_t[currentPacketSize]);
if (buffer == nullptr) {
return;
}
_udp.read(buffer.get(), currentPacketSize);
if (_dns.isSet() && _udp.remoteIP() == _dns) {
// _forwarder may have been set to false; however, for now allow in-flight
// replies to finish. //??
forwardReply(buffer.get(), currentPacketSize);
} else if (respondToRequest(buffer.get(), currentPacketSize)) {
forwardRequest(buffer.get(), currentPacketSize);
}
}
void DNSServer::writeNBOShort(uint16_t value) {
_udp.write((unsigned char *)&value, 2);
}
void DNSServer::replyWithIP(DNSHeader *dnsHeader,
unsigned char * query,
size_t queryLength)
{
uint16_t value;
unsigned char * query,
size_t queryLength) {
uint16_t value;
dnsHeader->QR = DNS_QR_RESPONSE;
dnsHeader->QDCount = lwip_htons(1);
dnsHeader->ANCount = lwip_htons(1);
dnsHeader->NSCount = 0;
dnsHeader->ARCount = 0;
dnsHeader->QR = DNS_QR_RESPONSE;
dnsHeader->QDCount = lwip_htons(1);
dnsHeader->ANCount = lwip_htons(1);
dnsHeader->NSCount = 0;
dnsHeader->ARCount = 0;
_udp.beginPacket(_udp.remoteIP(), _udp.remotePort());
_udp.write((unsigned char *) dnsHeader, sizeof(DNSHeader));
_udp.write(query, queryLength);
_udp.beginPacket(_udp.remoteIP(), _udp.remotePort());
_udp.write((unsigned char *) dnsHeader, sizeof(DNSHeader));
_udp.write(query, queryLength);
// Rather than restate the name here, we use a pointer to the name contained
// in the query section. Pointers have the top two bits set.
value = 0xC000 | DNS_HEADER_SIZE;
writeNBOShort(lwip_htons(value));
// Rather than restate the name here, we use a pointer to the name contained
// in the query section. Pointers have the top two bits set.
value = 0xC000 | DNS_HEADER_SIZE;
writeNBOShort(lwip_htons(value));
// Answer is type A (an IPv4 address)
writeNBOShort(lwip_htons(DNS_QTYPE_A));
// Answer is type A (an IPv4 address)
writeNBOShort(lwip_htons(DNS_QTYPE_A));
// Answer is in the Internet Class
writeNBOShort(lwip_htons(DNS_QCLASS_IN));
// Answer is in the Internet Class
writeNBOShort(lwip_htons(DNS_QCLASS_IN));
// Output TTL (already NBO)
_udp.write((unsigned char*)&_ttl, 4);
// Output TTL (already NBO)
_udp.write((unsigned char*)&_ttl, 4);
// Length of RData is 4 bytes (because, in this case, RData is IPv4)
writeNBOShort(lwip_htons(sizeof(_resolvedIP)));
_udp.write(_resolvedIP, sizeof(_resolvedIP));
_udp.endPacket();
// Length of RData is 4 bytes (because, in this case, RData is IPv4)
writeNBOShort(lwip_htons(sizeof(_resolvedIP)));
_udp.write(_resolvedIP, sizeof(_resolvedIP));
_udp.endPacket();
}
void DNSServer::replyWithError(DNSHeader *dnsHeader,
DNSReplyCode rcode,
unsigned char *query,
size_t queryLength)
{
dnsHeader->QR = DNS_QR_RESPONSE;
dnsHeader->RCode = (unsigned char) rcode;
if (query)
dnsHeader->QDCount = lwip_htons(1);
else
dnsHeader->QDCount = 0;
dnsHeader->ANCount = 0;
dnsHeader->NSCount = 0;
dnsHeader->ARCount = 0;
DNSReplyCode rcode,
unsigned char *query,
size_t queryLength) {
dnsHeader->QR = DNS_QR_RESPONSE;
dnsHeader->RCode = (unsigned char) rcode;
if (query) {
dnsHeader->QDCount = lwip_htons(1);
} else {
dnsHeader->QDCount = 0;
}
dnsHeader->ANCount = 0;
dnsHeader->NSCount = 0;
dnsHeader->ARCount = 0;
_udp.beginPacket(_udp.remoteIP(), _udp.remotePort());
_udp.write((unsigned char *)dnsHeader, sizeof(DNSHeader));
if (query != NULL)
_udp.write(query, queryLength);
_udp.endPacket();
_udp.beginPacket(_udp.remoteIP(), _udp.remotePort());
_udp.write((unsigned char *)dnsHeader, sizeof(DNSHeader));
if (query != NULL) {
_udp.write(query, queryLength);
}
_udp.endPacket();
}
void DNSServer::replyWithError(DNSHeader *dnsHeader,
DNSReplyCode rcode)
{
replyWithError(dnsHeader, rcode, NULL, 0);
DNSReplyCode rcode) {
replyWithError(dnsHeader, rcode, NULL, 0);
}

View file

@ -1,5 +1,25 @@
#ifndef DNSServer_h
#define DNSServer_h
/*
DNSServer.cwhcpp - Simple DNS server for the Pico
Modified 2022 Earle F. Philhower, III. All rights reserved.
Taken from the ESP8266 core libraries, (c) various authors.
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
*/
#pragma once
#include <memory>
#include <WiFiUdp.h>
@ -25,90 +45,97 @@ constexpr inline uint16_t kIanaDnsPort = IANA_DNS_PORT;
#define MAX_DNSNAME_LENGTH 253
#define MAX_DNS_PACKETSIZE 512
enum class DNSReplyCode
{
NoError = 0,
FormError = 1,
ServerFailure = 2,
NonExistentDomain = 3,
NotImplemented = 4,
Refused = 5,
YXDomain = 6,
YXRRSet = 7,
NXRRSet = 8
enum class DNSReplyCode {
NoError = 0,
FormError = 1,
ServerFailure = 2,
NonExistentDomain = 3,
NotImplemented = 4,
Refused = 5,
YXDomain = 6,
YXRRSet = 7,
NXRRSet = 8
};
struct DNSHeader
{
uint16_t ID; // identification number
unsigned char RD : 1; // recursion desired
unsigned char TC : 1; // truncated message
unsigned char AA : 1; // authoritative answer
unsigned char OPCode : 4; // message_type
unsigned char QR : 1; // query/response flag
unsigned char RCode : 4; // response code
unsigned char Z : 3; // its z! reserved
unsigned char RA : 1; // recursion available
uint16_t QDCount; // number of question entries
uint16_t ANCount; // number of answer entries
uint16_t NSCount; // number of authority entries
uint16_t ARCount; // number of resource entries
struct DNSHeader {
uint16_t ID; // identification number
unsigned char RD : 1; // recursion desired
unsigned char TC : 1; // truncated message
unsigned char AA : 1; // authoritative answer
unsigned char OPCode : 4; // message_type
unsigned char QR : 1; // query/response flag
unsigned char RCode : 4; // response code
unsigned char Z : 3; // its z! reserved
unsigned char RA : 1; // recursion available
uint16_t QDCount; // number of question entries
uint16_t ANCount; // number of answer entries
uint16_t NSCount; // number of authority entries
uint16_t ARCount; // number of resource entries
};
constexpr inline size_t kDNSSQueSizeAddrBits = 3; // The number of bits used to address que entries
constexpr inline size_t kDNSSQueSize = (1UL << (kDNSSQueSizeAddrBits));
constexpr inline size_t kDNSSQueSize = (1UL << (kDNSSQueSizeAddrBits));
struct DNSS_REQUESTER {
uint32_t ip;
uint16_t port;
uint16_t id;
uint32_t ip;
uint16_t port;
uint16_t id;
};
class DNSServer
{
public:
class DNSServer {
public:
DNSServer();
~DNSServer() {
stop();
};
/*
If specified, `enableForwarder` will update the `domainName` that is used
to match DNS request to this AP's IP Address. A non-matching request will
be forwarded to the DNS server specified by `dns`.
If specified, `enableForwarder` will update the `domainName` that is used
to match DNS request to this AP's IP Address. A non-matching request will
be forwarded to the DNS server specified by `dns`.
Returns `true` on success.
Returns `true` on success.
Returns `false`,
* when forwarding `dns` is not set, or
* unable to allocate resources for managing the DNS forward function.
Returns `false`,
when forwarding `dns` is not set, or
unable to allocate resources for managing the DNS forward function.
*/
bool enableForwarder(const String &domainName = String(""), const IPAddress &dns = (uint32_t)0);
/*
`disableForwarder` will stop forwarding DNS requests. If specified,
updates the `domainName` that is matched for returning this AP's IP Address.
Optionally, resources used for the DNS forward function can be freed.
`disableForwarder` will stop forwarding DNS requests. If specified,
updates the `domainName` that is matched for returning this AP's IP Address.
Optionally, resources used for the DNS forward function can be freed.
*/
void disableForwarder(const String &domainName = String(""), bool freeResources = false);
bool isForwarding() { return _forwarder && _dns.isSet(); }
void setDNS(const IPAddress& dns) { _dns = dns; }
IPAddress getDNS() { return _dns; }
bool isDNSSet() { return _dns.isSet(); }
bool isForwarding() {
return _forwarder && _dns.isSet();
}
void setDNS(const IPAddress& dns) {
_dns = dns;
}
IPAddress getDNS() {
return _dns;
}
bool isDNSSet() {
return _dns.isSet();
}
void processNextRequest();
void setErrorReplyCode(const DNSReplyCode &replyCode);
void setTTL(const uint32_t &ttl);
uint32_t getTTL();
String getDomainName() { return _domainName; }
String getDomainName() {
return _domainName;
}
// Returns true if successful, false if there are no sockets available
bool start(const uint16_t &port,
const String &domainName,
const IPAddress &resolvedIP,
const IPAddress &dns = (uint32_t)0);
const String &domainName,
const IPAddress &resolvedIP,
const IPAddress &dns = (uint32_t)0);
// stops the DNS server
void stop();
private:
private:
WiFiUDP _udp;
String _domainName;
IPAddress _dns;
@ -128,17 +155,16 @@ class DNSServer
void downcaseAndRemoveWwwPrefix(String &domainName);
void replyWithIP(DNSHeader *dnsHeader,
unsigned char * query,
size_t queryLength);
unsigned char * query,
size_t queryLength);
void replyWithError(DNSHeader *dnsHeader,
DNSReplyCode rcode,
unsigned char *query,
size_t queryLength);
DNSReplyCode rcode,
unsigned char *query,
size_t queryLength);
void replyWithError(DNSHeader *dnsHeader,
DNSReplyCode rcode);
DNSReplyCode rcode);
bool respondToRequest(uint8_t *buffer, size_t length);
void forwardRequest(uint8_t *buffer, size_t length);
void forwardReply(uint8_t *buffer, size_t length);
void writeNBOShort(uint16_t value);
};
#endif

View file

@ -19,8 +19,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef EEPROM_h
#define EEPROM_h
#pragma once
#include <stddef.h>
#include <stdint.h>
@ -85,6 +84,3 @@ protected:
};
extern EEPROMClass EEPROM;
#endif

View file

@ -1,3 +1,24 @@
/*
HTTPUpdateServer - Support simple web based OTA
Modified 2022 Earle F. Philhower, III. All rights reserved.
Ported from the ESP8266 Arduino core, (c) copyright multiple authors
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
*/
#pragma once
#include <Arduino.h>

View file

@ -1,3 +1,24 @@
/*
HTTPUpdateServer - Support simple web based OTA
Modified 2022 Earle F. Philhower, III. All rights reserved.
Ported from the ESP8266 Arduino core, (c) copyright multiple authors
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
*/
#pragma once
#include <WebServer.h>

View file

@ -22,8 +22,7 @@
*/
#ifndef MDNS_PRIV_H
#define MDNS_PRIV_H
#pragma once
namespace esp8266 {
@ -186,5 +185,3 @@ namespace MDNSImplementation {
// Include the main header, so the submodlues only need to include this header
#include "LEAmDNS.h"
#endif // MDNS_PRIV_H

View file

@ -22,9 +22,6 @@
*/
#ifndef MDNS_LWIPDEFS_H
#define MDNS_LWIPDEFS_H
#pragma once
#include <lwip/prot/dns.h> // DNS_RRTYPE_xxx, DNS_MQUERY_PORT
#endif // MDNS_LWIPDEFS_H

View file

@ -23,9 +23,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __LITTLEFS_H
#define __LITTLEFS_H
#pragma once
#include <limits>
#include <FS.h>
@ -681,6 +679,3 @@ protected:
extern FS LittleFS;
using littlefs_impl::LittleFSConfig;
#endif // ARDUINO
#endif // !defined(__LITTLEFS_H)

View file

@ -52,7 +52,7 @@ void loop() {
// Print samples to the serial monitor or plotter
for (int i = 0; i < samplesRead; i++) {
if(channels == 2) {
if (channels == 2) {
Serial.print("L:");
Serial.print(sampleBuffer[i]);
Serial.print(" R:");
@ -67,9 +67,9 @@ void loop() {
}
/**
* Callback function to process the data from the PDM microphone.
* NOTE: This callback is executed as part of an ISR.
* Therefore using `Serial` to print messages inside this function isn't supported.
Callback function to process the data from the PDM microphone.
NOTE: This callback is executed as part of an ISR.
Therefore using `Serial` to print messages inside this function isn't supported.
* */
void onPDMdata() {
// Query the number of available bytes

View file

@ -1,74 +1,72 @@
/*
Copyright (c) 2019 Arduino LLC. All right reserved.
Copyright (c) 2019 Arduino LLC. 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 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.
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
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 _PDM_H_INCLUDED
#define _PDM_H_INCLUDED
#pragma once
#include <Arduino.h>
//#include <pinDefinitions.h>
#include "utility/PDMDoubleBuffer.h"
class PDMClass
{
class PDMClass {
public:
PDMClass(int dinPin, int clkPin, int pwrPin);
virtual ~PDMClass();
PDMClass(int dinPin, int clkPin, int pwrPin);
virtual ~PDMClass();
int begin(int channels, int sampleRate);
void end();
int begin(int channels, int sampleRate);
void end();
virtual int available();
virtual int read(void* buffer, size_t size);
virtual int available();
virtual int read(void* buffer, size_t size);
void onReceive(void(*)(void));
void onReceive(void(*)(void));
//PORTENTA_H7 min -12 max 51
//NANO 33 BLE SENSe min 0 max 80
void setGain(int gain);
void setBufferSize(int bufferSize);
size_t getBufferSize();
//PORTENTA_H7 min -12 max 51
//NANO 33 BLE SENSe min 0 max 80
void setGain(int gain);
void setBufferSize(int bufferSize);
size_t getBufferSize();
// private:
void IrqHandler(bool halftranfer);
// private:
void IrqHandler(bool halftranfer);
private:
int _dinPin;
int _clkPin;
int _pwrPin;
int _dinPin;
int _clkPin;
int _pwrPin;
int _channels;
int _samplerate;
int _channels;
int _samplerate;
int _gain;
int _init;
int _gain;
int _init;
// Hardware peripherals used
uint _dmaChannel;
PIO _pio;
int _smIdx;
int _pgmOffset;
// Hardware peripherals used
uint _dmaChannel;
PIO _pio;
int _smIdx;
int _pgmOffset;
PDMDoubleBuffer _doubleBuffer;
PDMDoubleBuffer _doubleBuffer;
void (*_onReceive)(void);
void (*_onReceive)(void);
};
#ifdef PIN_PDM_DIN
extern PDMClass PDM;
#endif
#endif

View file

@ -1,30 +1,30 @@
/**
*******************************************************************************
* @file OpenPDMFilter.c
* @author CL
* @version V1.0.0
* @date 9-September-2015
* @brief Open PDM audio software decoding Library.
* This Library is used to decode and reconstruct the audio signal
* produced by ST MEMS microphone (MP45Dxxx, MP34Dxxx).
@file OpenPDMFilter.c
@author CL
@version V1.0.0
@date 9-September-2015
@brief Open PDM audio software decoding Library.
This Library is used to decode and reconstruct the audio signal
produced by ST MEMS microphone (MP45Dxxx, MP34Dxxx).
*******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2018 STMicroelectronics</center></h2>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
@attention
<h2><center>&copy; COPYRIGHT 2018 STMicroelectronics</center></h2>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*******************************************************************************
*/
*/
/* Includes ------------------------------------------------------------------*/
@ -48,266 +48,255 @@ int32_t lut[256][DECIMATION_MAX / 8][SINCN];
/* Functions -----------------------------------------------------------------*/
#ifdef USE_LUT
int32_t filter_table_mono_64(uint8_t *data, uint8_t sincn)
{
return (int32_t)
lut[data[0]][0][sincn] +
lut[data[1]][1][sincn] +
lut[data[2]][2][sincn] +
lut[data[3]][3][sincn] +
lut[data[4]][4][sincn] +
lut[data[5]][5][sincn] +
lut[data[6]][6][sincn] +
lut[data[7]][7][sincn];
int32_t filter_table_mono_64(uint8_t *data, uint8_t sincn) {
return (int32_t)
lut[data[0]][0][sincn] +
lut[data[1]][1][sincn] +
lut[data[2]][2][sincn] +
lut[data[3]][3][sincn] +
lut[data[4]][4][sincn] +
lut[data[5]][5][sincn] +
lut[data[6]][6][sincn] +
lut[data[7]][7][sincn];
}
int32_t filter_table_stereo_64(uint8_t *data, uint8_t sincn)
{
return (int32_t)
lut[data[0]][0][sincn] +
lut[data[2]][1][sincn] +
lut[data[4]][2][sincn] +
lut[data[6]][3][sincn] +
lut[data[8]][4][sincn] +
lut[data[10]][5][sincn] +
lut[data[12]][6][sincn] +
lut[data[14]][7][sincn];
int32_t filter_table_stereo_64(uint8_t *data, uint8_t sincn) {
return (int32_t)
lut[data[0]][0][sincn] +
lut[data[2]][1][sincn] +
lut[data[4]][2][sincn] +
lut[data[6]][3][sincn] +
lut[data[8]][4][sincn] +
lut[data[10]][5][sincn] +
lut[data[12]][6][sincn] +
lut[data[14]][7][sincn];
}
int32_t filter_table_mono_128(uint8_t *data, uint8_t sincn)
{
return (int32_t)
lut[data[0]][0][sincn] +
lut[data[1]][1][sincn] +
lut[data[2]][2][sincn] +
lut[data[3]][3][sincn] +
lut[data[4]][4][sincn] +
lut[data[5]][5][sincn] +
lut[data[6]][6][sincn] +
lut[data[7]][7][sincn] +
lut[data[8]][8][sincn] +
lut[data[9]][9][sincn] +
lut[data[10]][10][sincn] +
lut[data[11]][11][sincn] +
lut[data[12]][12][sincn] +
lut[data[13]][13][sincn] +
lut[data[14]][14][sincn] +
lut[data[15]][15][sincn];
int32_t filter_table_mono_128(uint8_t *data, uint8_t sincn) {
return (int32_t)
lut[data[0]][0][sincn] +
lut[data[1]][1][sincn] +
lut[data[2]][2][sincn] +
lut[data[3]][3][sincn] +
lut[data[4]][4][sincn] +
lut[data[5]][5][sincn] +
lut[data[6]][6][sincn] +
lut[data[7]][7][sincn] +
lut[data[8]][8][sincn] +
lut[data[9]][9][sincn] +
lut[data[10]][10][sincn] +
lut[data[11]][11][sincn] +
lut[data[12]][12][sincn] +
lut[data[13]][13][sincn] +
lut[data[14]][14][sincn] +
lut[data[15]][15][sincn];
}
int32_t filter_table_stereo_128(uint8_t *data, uint8_t sincn)
{
return (int32_t)
lut[data[0]][0][sincn] +
lut[data[2]][1][sincn] +
lut[data[4]][2][sincn] +
lut[data[6]][3][sincn] +
lut[data[8]][4][sincn] +
lut[data[10]][5][sincn] +
lut[data[12]][6][sincn] +
lut[data[14]][7][sincn] +
lut[data[16]][8][sincn] +
lut[data[18]][9][sincn] +
lut[data[20]][10][sincn] +
lut[data[22]][11][sincn] +
lut[data[24]][12][sincn] +
lut[data[26]][13][sincn] +
lut[data[28]][14][sincn] +
lut[data[30]][15][sincn];
int32_t filter_table_stereo_128(uint8_t *data, uint8_t sincn) {
return (int32_t)
lut[data[0]][0][sincn] +
lut[data[2]][1][sincn] +
lut[data[4]][2][sincn] +
lut[data[6]][3][sincn] +
lut[data[8]][4][sincn] +
lut[data[10]][5][sincn] +
lut[data[12]][6][sincn] +
lut[data[14]][7][sincn] +
lut[data[16]][8][sincn] +
lut[data[18]][9][sincn] +
lut[data[20]][10][sincn] +
lut[data[22]][11][sincn] +
lut[data[24]][12][sincn] +
lut[data[26]][13][sincn] +
lut[data[28]][14][sincn] +
lut[data[30]][15][sincn];
}
int32_t (* filter_tables_64[2]) (uint8_t *data, uint8_t sincn) = {filter_table_mono_64, filter_table_stereo_64};
int32_t (* filter_tables_128[2]) (uint8_t *data, uint8_t sincn) = {filter_table_mono_128, filter_table_stereo_128};
int32_t (* filter_tables_64[2])(uint8_t *data, uint8_t sincn) = {filter_table_mono_64, filter_table_stereo_64};
int32_t (* filter_tables_128[2])(uint8_t *data, uint8_t sincn) = {filter_table_mono_128, filter_table_stereo_128};
#else
int32_t filter_table(uint8_t *data, uint8_t sincn, TPDMFilter_InitStruct *param)
{
uint8_t c, i;
uint16_t data_index = 0;
uint32_t *coef_p = &coef[sincn][0];
int32_t F = 0;
uint8_t decimation = param->Decimation;
uint8_t channels = param->In_MicChannels;
int32_t filter_table(uint8_t *data, uint8_t sincn, TPDMFilter_InitStruct *param) {
uint8_t c, i;
uint16_t data_index = 0;
uint32_t *coef_p = &coef[sincn][0];
int32_t F = 0;
uint8_t decimation = param->Decimation;
uint8_t channels = param->In_MicChannels;
for (i = 0; i < decimation; i += 8) {
c = data[data_index];
F += ((c >> 7) ) * coef_p[i ] +
((c >> 6) & 0x01) * coef_p[i + 1] +
((c >> 5) & 0x01) * coef_p[i + 2] +
((c >> 4) & 0x01) * coef_p[i + 3] +
((c >> 3) & 0x01) * coef_p[i + 4] +
((c >> 2) & 0x01) * coef_p[i + 5] +
((c >> 1) & 0x01) * coef_p[i + 6] +
((c ) & 0x01) * coef_p[i + 7];
data_index += channels;
}
return F;
for (i = 0; i < decimation; i += 8) {
c = data[data_index];
F += ((c >> 7)) * coef_p[i ] +
((c >> 6) & 0x01) * coef_p[i + 1] +
((c >> 5) & 0x01) * coef_p[i + 2] +
((c >> 4) & 0x01) * coef_p[i + 3] +
((c >> 3) & 0x01) * coef_p[i + 4] +
((c >> 2) & 0x01) * coef_p[i + 5] +
((c >> 1) & 0x01) * coef_p[i + 6] +
((c) & 0x01) * coef_p[i + 7];
data_index += channels;
}
return F;
}
#endif
void convolve(uint32_t Signal[/* SignalLen */], unsigned short SignalLen,
uint32_t Kernel[/* KernelLen */], unsigned short KernelLen,
uint32_t Result[/* SignalLen + KernelLen - 1 */])
{
uint16_t n;
uint32_t Result[/* SignalLen + KernelLen - 1 */]) {
uint16_t n;
for (n = 0; n < SignalLen + KernelLen - 1; n++)
{
unsigned short kmin, kmax, k;
Result[n] = 0;
kmin = (n >= KernelLen - 1) ? n - (KernelLen - 1) : 0;
kmax = (n < SignalLen - 1) ? n : SignalLen - 1;
for (k = kmin; k <= kmax; k++) {
Result[n] += Signal[k] * Kernel[n - k];
for (n = 0; n < SignalLen + KernelLen - 1; n++) {
unsigned short kmin, kmax, k;
Result[n] = 0;
kmin = (n >= KernelLen - 1) ? n - (KernelLen - 1) : 0;
kmax = (n < SignalLen - 1) ? n : SignalLen - 1;
for (k = kmin; k <= kmax; k++) {
Result[n] += Signal[k] * Kernel[n - k];
}
}
}
}
void Open_PDM_Filter_Init(TPDMFilter_InitStruct *Param)
{
uint16_t i, j;
int64_t sum = 0;
void Open_PDM_Filter_Init(TPDMFilter_InitStruct *Param) {
uint16_t i, j;
int64_t sum = 0;
uint8_t decimation = Param->Decimation;
uint8_t decimation = Param->Decimation;
for (i = 0; i < SINCN; i++) {
Param->Coef[i] = 0;
Param->bit[i] = 0;
}
for (i = 0; i < decimation; i++) {
sinc1[i] = 1;
}
Param->OldOut = Param->OldIn = Param->OldZ = 0;
Param->LP_ALFA = (Param->LP_HZ != 0 ? (uint16_t) (Param->LP_HZ * 256 / (Param->LP_HZ + Param->Fs / (2 * 3.14159))) : 0);
Param->HP_ALFA = (Param->HP_HZ != 0 ? (uint16_t) (Param->Fs * 256 / (2 * 3.14159 * Param->HP_HZ + Param->Fs)) : 0);
Param->FilterLen = decimation * SINCN;
sinc[0] = 0;
sinc[decimation * SINCN - 1] = 0;
convolve(sinc1, decimation, sinc1, decimation, sinc2);
convolve(sinc2, decimation * 2 - 1, sinc1, decimation, &sinc[1]);
for(j = 0; j < SINCN; j++) {
for (i = 0; i < SINCN; i++) {
Param->Coef[i] = 0;
Param->bit[i] = 0;
}
for (i = 0; i < decimation; i++) {
coef[j][i] = sinc[j * decimation + i];
sum += sinc[j * decimation + i];
sinc1[i] = 1;
}
}
sub_const = sum >> 1;
div_const = sub_const * Param->MaxVolume / 32768 / Param->filterGain;
div_const = (div_const == 0 ? 1 : div_const);
Param->OldOut = Param->OldIn = Param->OldZ = 0;
Param->LP_ALFA = (Param->LP_HZ != 0 ? (uint16_t)(Param->LP_HZ * 256 / (Param->LP_HZ + Param->Fs / (2 * 3.14159))) : 0);
Param->HP_ALFA = (Param->HP_HZ != 0 ? (uint16_t)(Param->Fs * 256 / (2 * 3.14159 * Param->HP_HZ + Param->Fs)) : 0);
Param->FilterLen = decimation * SINCN;
sinc[0] = 0;
sinc[decimation * SINCN - 1] = 0;
convolve(sinc1, decimation, sinc1, decimation, sinc2);
convolve(sinc2, decimation * 2 - 1, sinc1, decimation, &sinc[1]);
for (j = 0; j < SINCN; j++) {
for (i = 0; i < decimation; i++) {
coef[j][i] = sinc[j * decimation + i];
sum += sinc[j * decimation + i];
}
}
sub_const = sum >> 1;
div_const = sub_const * Param->MaxVolume / 32768 / Param->filterGain;
div_const = (div_const == 0 ? 1 : div_const);
#ifdef USE_LUT
/* Look-Up Table. */
uint16_t c, d, s;
for (s = 0; s < SINCN; s++)
{
uint32_t *coef_p = &coef[s][0];
for (c = 0; c < 256; c++)
for (d = 0; d < decimation / 8; d++)
lut[c][d][s] = ((c >> 7) ) * coef_p[d * 8 ] +
((c >> 6) & 0x01) * coef_p[d * 8 + 1] +
((c >> 5) & 0x01) * coef_p[d * 8 + 2] +
((c >> 4) & 0x01) * coef_p[d * 8 + 3] +
((c >> 3) & 0x01) * coef_p[d * 8 + 4] +
((c >> 2) & 0x01) * coef_p[d * 8 + 5] +
((c >> 1) & 0x01) * coef_p[d * 8 + 6] +
((c ) & 0x01) * coef_p[d * 8 + 7];
}
/* Look-Up Table. */
uint16_t c, d, s;
for (s = 0; s < SINCN; s++) {
uint32_t *coef_p = &coef[s][0];
for (c = 0; c < 256; c++)
for (d = 0; d < decimation / 8; d++)
lut[c][d][s] = ((c >> 7)) * coef_p[d * 8 ] +
((c >> 6) & 0x01) * coef_p[d * 8 + 1] +
((c >> 5) & 0x01) * coef_p[d * 8 + 2] +
((c >> 4) & 0x01) * coef_p[d * 8 + 3] +
((c >> 3) & 0x01) * coef_p[d * 8 + 4] +
((c >> 2) & 0x01) * coef_p[d * 8 + 5] +
((c >> 1) & 0x01) * coef_p[d * 8 + 6] +
((c) & 0x01) * coef_p[d * 8 + 7];
}
#endif
}
void Open_PDM_Filter_64(uint8_t* data, int16_t* dataOut, uint16_t volume, TPDMFilter_InitStruct *Param)
{
uint8_t i, data_out_index;
uint8_t channels = Param->In_MicChannels;
uint8_t data_inc = ((DECIMATION_MAX >> 4) * channels);
int64_t Z, Z0, Z1, Z2;
int64_t OldOut, OldIn, OldZ;
void Open_PDM_Filter_64(uint8_t* data, int16_t* dataOut, uint16_t volume, TPDMFilter_InitStruct *Param) {
uint8_t i, data_out_index;
uint8_t channels = Param->In_MicChannels;
uint8_t data_inc = ((DECIMATION_MAX >> 4) * channels);
int64_t Z, Z0, Z1, Z2;
int64_t OldOut, OldIn, OldZ;
OldOut = Param->OldOut;
OldIn = Param->OldIn;
OldZ = Param->OldZ;
OldOut = Param->OldOut;
OldIn = Param->OldIn;
OldZ = Param->OldZ;
#ifdef USE_LUT
uint8_t j = channels - 1;
uint8_t j = channels - 1;
#endif
for (i = 0, data_out_index = 0; i < Param->nSamples; i++, data_out_index += channels) {
for (i = 0, data_out_index = 0; i < Param->nSamples; i++, data_out_index += channels) {
#ifdef USE_LUT
Z0 = filter_tables_64[j](data, 0);
Z1 = filter_tables_64[j](data, 1);
Z2 = filter_tables_64[j](data, 2);
Z0 = filter_tables_64[j](data, 0);
Z1 = filter_tables_64[j](data, 1);
Z2 = filter_tables_64[j](data, 2);
#else
Z0 = filter_table(data, 0, Param);
Z1 = filter_table(data, 1, Param);
Z2 = filter_table(data, 2, Param);
Z0 = filter_table(data, 0, Param);
Z1 = filter_table(data, 1, Param);
Z2 = filter_table(data, 2, Param);
#endif
Z = Param->Coef[1] + Z2 - sub_const;
Param->Coef[1] = Param->Coef[0] + Z1;
Param->Coef[0] = Z0;
Z = Param->Coef[1] + Z2 - sub_const;
Param->Coef[1] = Param->Coef[0] + Z1;
Param->Coef[0] = Z0;
OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn)) >> 8;
OldIn = Z;
OldZ = ((256 - Param->LP_ALFA) * OldZ + Param->LP_ALFA * OldOut) >> 8;
OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn)) >> 8;
OldIn = Z;
OldZ = ((256 - Param->LP_ALFA) * OldZ + Param->LP_ALFA * OldOut) >> 8;
Z = OldZ * volume;
Z = RoundDiv(Z, div_const);
Z = SaturaLH(Z, -32700, 32700);
Z = OldZ * volume;
Z = RoundDiv(Z, div_const);
Z = SaturaLH(Z, -32700, 32700);
dataOut[data_out_index] = Z;
data += data_inc;
}
dataOut[data_out_index] = Z;
data += data_inc;
}
Param->OldOut = OldOut;
Param->OldIn = OldIn;
Param->OldZ = OldZ;
Param->OldOut = OldOut;
Param->OldIn = OldIn;
Param->OldZ = OldZ;
}
void Open_PDM_Filter_128(uint8_t* data, int16_t* dataOut, uint16_t volume, TPDMFilter_InitStruct *Param)
{
uint8_t i, data_out_index;
uint8_t channels = Param->In_MicChannels;
uint8_t data_inc = ((DECIMATION_MAX >> 3) * channels);
int64_t Z, Z0, Z1, Z2;
int64_t OldOut, OldIn, OldZ;
void Open_PDM_Filter_128(uint8_t* data, int16_t* dataOut, uint16_t volume, TPDMFilter_InitStruct *Param) {
uint8_t i, data_out_index;
uint8_t channels = Param->In_MicChannels;
uint8_t data_inc = ((DECIMATION_MAX >> 3) * channels);
int64_t Z, Z0, Z1, Z2;
int64_t OldOut, OldIn, OldZ;
OldOut = Param->OldOut;
OldIn = Param->OldIn;
OldZ = Param->OldZ;
OldOut = Param->OldOut;
OldIn = Param->OldIn;
OldZ = Param->OldZ;
#ifdef USE_LUT
uint8_t j = channels - 1;
uint8_t j = channels - 1;
#endif
for (i = 0, data_out_index = 0; i < Param->nSamples; i++, data_out_index += channels) {
for (i = 0, data_out_index = 0; i < Param->nSamples; i++, data_out_index += channels) {
#ifdef USE_LUT
Z0 = filter_tables_128[j](data, 0);
Z1 = filter_tables_128[j](data, 1);
Z2 = filter_tables_128[j](data, 2);
Z0 = filter_tables_128[j](data, 0);
Z1 = filter_tables_128[j](data, 1);
Z2 = filter_tables_128[j](data, 2);
#else
Z0 = filter_table(data, 0, Param);
Z1 = filter_table(data, 1, Param);
Z2 = filter_table(data, 2, Param);
Z0 = filter_table(data, 0, Param);
Z1 = filter_table(data, 1, Param);
Z2 = filter_table(data, 2, Param);
#endif
Z = Param->Coef[1] + Z2 - sub_const;
Param->Coef[1] = Param->Coef[0] + Z1;
Param->Coef[0] = Z0;
Z = Param->Coef[1] + Z2 - sub_const;
Param->Coef[1] = Param->Coef[0] + Z1;
Param->Coef[0] = Z0;
OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn)) >> 8;
OldIn = Z;
OldZ = ((256 - Param->LP_ALFA) * OldZ + Param->LP_ALFA * OldOut) >> 8;
OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn)) >> 8;
OldIn = Z;
OldZ = ((256 - Param->LP_ALFA) * OldZ + Param->LP_ALFA * OldOut) >> 8;
Z = OldZ * volume;
Z = RoundDiv(Z, div_const);
Z = SaturaLH(Z, -32700, 32700);
Z = OldZ * volume;
Z = RoundDiv(Z, div_const);
Z = SaturaLH(Z, -32700, 32700);
dataOut[data_out_index] = Z;
data += data_inc;
}
dataOut[data_out_index] = Z;
data += data_inc;
}
Param->OldOut = OldOut;
Param->OldIn = OldIn;
Param->OldZ = OldZ;
Param->OldOut = OldOut;
Param->OldIn = OldIn;
Param->OldZ = OldZ;
}

View file

@ -1,30 +1,30 @@
/**
*******************************************************************************
* @file OpenPDMFilter.h
* @author CL
* @version V1.0.0
* @date 9-September-2015
* @brief Header file for Open PDM audio software decoding Library.
* This Library is used to decode and reconstruct the audio signal
* produced by ST MEMS microphone (MP45Dxxx, MP34Dxxx).
@file OpenPDMFilter.h
@author CL
@version V1.0.0
@date 9-September-2015
@brief Header file for Open PDM audio software decoding Library.
This Library is used to decode and reconstruct the audio signal
produced by ST MEMS microphone (MP45Dxxx, MP34Dxxx).
*******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2018 STMicroelectronics</center></h2>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
@attention
<h2><center>&copy; COPYRIGHT 2018 STMicroelectronics</center></h2>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*******************************************************************************
*/
*/
/* Define to prevent recursive inclusion -------------------------------------*/
@ -33,7 +33,7 @@
#define __OPENPDMFILTER_H
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif
@ -45,10 +45,10 @@
/* Definitions ---------------------------------------------------------------*/
/*
* Enable to use a Look-Up Table to improve performances while using more FLASH
* and RAM memory.
* Note: Without Look-Up Table up to stereo@16KHz configuration is supported.
*/
Enable to use a Look-Up Table to improve performances while using more FLASH
and RAM memory.
Note: Without Look-Up Table up to stereo@16KHz configuration is supported.
*/
#define USE_LUT
#define SINCN 3
@ -63,24 +63,24 @@
/* Types ---------------------------------------------------------------------*/
typedef struct {
/* Public */
float LP_HZ;
float HP_HZ;
uint16_t Fs;
unsigned int nSamples;
uint8_t In_MicChannels;
uint8_t Out_MicChannels;
uint8_t Decimation;
uint8_t MaxVolume;
/* Private */
uint32_t Coef[SINCN];
uint16_t FilterLen;
int64_t OldOut, OldIn, OldZ;
uint16_t LP_ALFA;
uint16_t HP_ALFA;
uint16_t bit[5];
uint16_t byte;
uint16_t filterGain;
/* Public */
float LP_HZ;
float HP_HZ;
uint16_t Fs;
unsigned int nSamples;
uint8_t In_MicChannels;
uint8_t Out_MicChannels;
uint8_t Decimation;
uint8_t MaxVolume;
/* Private */
uint32_t Coef[SINCN];
uint16_t FilterLen;
int64_t OldOut, OldIn, OldZ;
uint16_t LP_ALFA;
uint16_t HP_ALFA;
uint16_t bit[5];
uint16_t byte;
uint16_t filterGain;
} TPDMFilter_InitStruct;

View file

@ -9,7 +9,7 @@ extern "C" {
#include "hardware/dma.h"
#include "hardware/clocks.h"
}
#include "hardware/sync.h"
#include "hardware/sync.h"
#include "pdm.pio.h"
static PIOProgram _pdmPgm(&pdm_pio_program);
@ -18,7 +18,7 @@ static PIOProgram _pdmPgm(&pdm_pio_program);
uint8_t rawBuffer0[RAW_BUFFER_SIZE];
uint8_t rawBuffer1[RAW_BUFFER_SIZE];
uint8_t* rawBuffer[2] = {rawBuffer0, rawBuffer1};
volatile int rawBufferIndex = 0;
volatile int rawBufferIndex = 0;
int decimation = 64;
@ -30,179 +30,168 @@ int16_t* volatile finalBuffer;
TPDMFilter_InitStruct filter;
extern "C" {
__attribute__((__used__)) void dmaHandler(void)
{
PDM.IrqHandler(true);
}
__attribute__((__used__)) void dmaHandler(void) {
PDM.IrqHandler(true);
}
}
PDMClass::PDMClass(int dinPin, int clkPin, int pwrPin) :
_dinPin(dinPin),
_clkPin(clkPin),
_pwrPin(pwrPin),
_onReceive(NULL),
_gain(-1),
_channels(-1),
_samplerate(-1),
_init(-1),
_dmaChannel(0),
_pio(nullptr),
_smIdx(-1),
_pgmOffset(-1)
{
_dinPin(dinPin),
_clkPin(clkPin),
_pwrPin(pwrPin),
_onReceive(NULL),
_gain(-1),
_channels(-1),
_samplerate(-1),
_init(-1),
_dmaChannel(0),
_pio(nullptr),
_smIdx(-1),
_pgmOffset(-1) {
}
PDMClass::~PDMClass()
{
PDMClass::~PDMClass() {
}
int PDMClass::begin(int channels, int sampleRate)
{
//_channels = channels; // only one channel available
int PDMClass::begin(int channels, int sampleRate) {
//_channels = channels; // only one channel available
// clear the final buffers
_doubleBuffer.reset();
finalBuffer = (int16_t*)_doubleBuffer.data();
int finalBufferLength = _doubleBuffer.availableForWrite() / sizeof(int16_t);
_doubleBuffer.swap(0);
// clear the final buffers
_doubleBuffer.reset();
finalBuffer = (int16_t*)_doubleBuffer.data();
int finalBufferLength = _doubleBuffer.availableForWrite() / sizeof(int16_t);
_doubleBuffer.swap(0);
int rawBufferLength = RAW_BUFFER_SIZE / (decimation / 8);
// Saturate number of samples. Remaining bytes are dropped.
if (rawBufferLength > finalBufferLength) {
rawBufferLength = finalBufferLength;
}
int rawBufferLength = RAW_BUFFER_SIZE / (decimation / 8);
// Saturate number of samples. Remaining bytes are dropped.
if (rawBufferLength > finalBufferLength) {
rawBufferLength = finalBufferLength;
}
/* Initialize Open PDM library */
filter.Fs = sampleRate;
filter.nSamples = rawBufferLength;
filter.LP_HZ = sampleRate/2;
filter.HP_HZ = 10;
filter.In_MicChannels = 1;
filter.Out_MicChannels = 1;
filter.Decimation = decimation;
if(_gain == -1) {
_gain = FILTER_GAIN;
}
filter.filterGain = _gain;
Open_PDM_Filter_Init(&filter);
// Configure PIO state machine
float clkDiv = (float)clock_get_hz(clk_sys) / sampleRate / decimation / 2;
if (!_pdmPgm.prepare(&_pio, &_smIdx, &_pgmOffset)) {
// ERROR, no free slots
return -1;
}
pdm_pio_program_init(_pio, _smIdx, _pgmOffset, _clkPin, _dinPin, clkDiv);
// Wait for microphone
delay(100);
// Configure DMA for transferring PIO rx buffer to raw buffers
_dmaChannel = dma_claim_unused_channel(false);
dma_channel_config c = dma_channel_get_default_config(_dmaChannel);
channel_config_set_read_increment(&c, false);
channel_config_set_write_increment(&c, true);
channel_config_set_dreq(&c, pio_get_dreq(_pio, _smIdx, false));
channel_config_set_transfer_data_size(&c, DMA_SIZE_8);
// Clear DMA interrupts
dma_hw->ints0 = 1u << _dmaChannel;
// Enable DMA interrupts
dma_channel_set_irq0_enabled(_dmaChannel, true);
// Share but allocate a high priority to the interrupt
irq_add_shared_handler(DMA_IRQ_0, dmaHandler, 0);
irq_set_enabled(DMA_IRQ_0, true);
dma_channel_configure(_dmaChannel, &c,
rawBuffer[rawBufferIndex], // Destinatinon pointer
&_pio->rxf[_smIdx], // Source pointer
RAW_BUFFER_SIZE, // Number of transfers
true // Start immediately
);
_init = 1;
return 1;
}
void PDMClass::end()
{
dma_channel_abort(_dmaChannel);
pinMode(_clkPin, INPUT);
}
int PDMClass::available()
{
//NVIC_DisableIRQ(DMA_IRQ_0n);
//uint32_t interrupts = save_and_disable_interrupts();
irq_set_enabled(DMA_IRQ_0, false);
size_t avail = _doubleBuffer.available();
irq_set_enabled(DMA_IRQ_0, true);
//restore_interrupts(interrupts);
//NVIC_EnableIRQ(DMA_IRQ_0n);
return avail;
}
int PDMClass::read(void* buffer, size_t size)
{
irq_set_enabled(DMA_IRQ_0, false);
int read = _doubleBuffer.read(buffer, size);
irq_set_enabled(DMA_IRQ_0, true);
return read;
}
void PDMClass::onReceive(void(*function)(void))
{
_onReceive = function;
}
void PDMClass::setGain(int gain)
{
_gain = gain;
if(_init == 1) {
/* Initialize Open PDM library */
filter.Fs = sampleRate;
filter.nSamples = rawBufferLength;
filter.LP_HZ = sampleRate / 2;
filter.HP_HZ = 10;
filter.In_MicChannels = 1;
filter.Out_MicChannels = 1;
filter.Decimation = decimation;
if (_gain == -1) {
_gain = FILTER_GAIN;
}
filter.filterGain = _gain;
Open_PDM_Filter_Init(&filter);
}
// Configure PIO state machine
float clkDiv = (float)clock_get_hz(clk_sys) / sampleRate / decimation / 2;
if (!_pdmPgm.prepare(&_pio, &_smIdx, &_pgmOffset)) {
// ERROR, no free slots
return -1;
}
pdm_pio_program_init(_pio, _smIdx, _pgmOffset, _clkPin, _dinPin, clkDiv);
// Wait for microphone
delay(100);
// Configure DMA for transferring PIO rx buffer to raw buffers
_dmaChannel = dma_claim_unused_channel(false);
dma_channel_config c = dma_channel_get_default_config(_dmaChannel);
channel_config_set_read_increment(&c, false);
channel_config_set_write_increment(&c, true);
channel_config_set_dreq(&c, pio_get_dreq(_pio, _smIdx, false));
channel_config_set_transfer_data_size(&c, DMA_SIZE_8);
// Clear DMA interrupts
dma_hw->ints0 = 1u << _dmaChannel;
// Enable DMA interrupts
dma_channel_set_irq0_enabled(_dmaChannel, true);
// Share but allocate a high priority to the interrupt
irq_add_shared_handler(DMA_IRQ_0, dmaHandler, 0);
irq_set_enabled(DMA_IRQ_0, true);
dma_channel_configure(_dmaChannel, &c,
rawBuffer[rawBufferIndex], // Destinatinon pointer
&_pio->rxf[_smIdx], // Source pointer
RAW_BUFFER_SIZE, // Number of transfers
true // Start immediately
);
_init = 1;
return 1;
}
void PDMClass::setBufferSize(int bufferSize)
{
_doubleBuffer.setSize(bufferSize);
void PDMClass::end() {
dma_channel_abort(_dmaChannel);
pinMode(_clkPin, INPUT);
}
void PDMClass::IrqHandler(bool halftranfer)
{
static int cutSamples = 100;
int PDMClass::available() {
//NVIC_DisableIRQ(DMA_IRQ_0n);
//uint32_t interrupts = save_and_disable_interrupts();
irq_set_enabled(DMA_IRQ_0, false);
size_t avail = _doubleBuffer.available();
irq_set_enabled(DMA_IRQ_0, true);
//restore_interrupts(interrupts);
//NVIC_EnableIRQ(DMA_IRQ_0n);
return avail;
}
// Clear the interrupt request.
dma_hw->ints0 = 1u << _dmaChannel;
// Restart dma pointing to the other buffer
int shadowIndex = rawBufferIndex ^ 1;
dma_channel_set_write_addr(_dmaChannel, rawBuffer[shadowIndex], true);
int PDMClass::read(void* buffer, size_t size) {
irq_set_enabled(DMA_IRQ_0, false);
int read = _doubleBuffer.read(buffer, size);
irq_set_enabled(DMA_IRQ_0, true);
return read;
}
if (_doubleBuffer.available()) {
// buffer overflow, stop
return end();
}
void PDMClass::onReceive(void(*function)(void)) {
_onReceive = function;
}
// fill final buffer with PCM samples
Open_PDM_Filter_64(rawBuffer[rawBufferIndex], finalBuffer, 1, &filter);
void PDMClass::setGain(int gain) {
_gain = gain;
if (_init == 1) {
filter.filterGain = _gain;
Open_PDM_Filter_Init(&filter);
}
}
if (cutSamples) {
memset(finalBuffer, 0, cutSamples);
cutSamples = 0;
}
void PDMClass::setBufferSize(int bufferSize) {
_doubleBuffer.setSize(bufferSize);
}
// swap final buffer and raw buffers' indexes
finalBuffer = (int16_t*)_doubleBuffer.data();
_doubleBuffer.swap(filter.nSamples * sizeof(int16_t));
rawBufferIndex = shadowIndex;
void PDMClass::IrqHandler(bool halftranfer) {
static int cutSamples = 100;
if (_onReceive) {
_onReceive();
}
// Clear the interrupt request.
dma_hw->ints0 = 1u << _dmaChannel;
// Restart dma pointing to the other buffer
int shadowIndex = rawBufferIndex ^ 1;
dma_channel_set_write_addr(_dmaChannel, rawBuffer[shadowIndex], true);
if (_doubleBuffer.available()) {
// buffer overflow, stop
return end();
}
// fill final buffer with PCM samples
Open_PDM_Filter_64(rawBuffer[rawBufferIndex], finalBuffer, 1, &filter);
if (cutSamples) {
memset(finalBuffer, 0, cutSamples);
cutSamples = 0;
}
// swap final buffer and raw buffers' indexes
finalBuffer = (int16_t*)_doubleBuffer.data();
_doubleBuffer.swap(filter.nSamples * sizeof(int16_t));
rawBufferIndex = shadowIndex;
if (_onReceive) {
_onReceive();
}
}
#ifdef PIN_PDM_DIN
PDMClass PDM(PIN_PDM_DIN, PIN_PDM_CLK, -1);

View file

@ -14,10 +14,10 @@
#define pdm_pio_wrap 1
static const uint16_t pdm_pio_program_instructions[] = {
// .wrap_target
0x9040, // 0: push iffull noblock side 1
0x4001, // 1: in pins, 1 side 0
// .wrap
// .wrap_target
0x9040, // 0: push iffull noblock side 1
0x4001, // 1: in pins, 1 side 0
// .wrap
};
#if !PICO_NO_HARDWARE
@ -36,21 +36,21 @@ static inline pio_sm_config pdm_pio_program_get_default_config(uint offset) {
#include "hardware/gpio.h"
static inline void pdm_pio_program_init(PIO pio, uint sm, uint offset, uint clkPin, uint dataPin, float clkDiv) {
pio_sm_config c = pdm_pio_program_get_default_config(offset);
sm_config_set_sideset(&c, 1, false, false);
//sm_config_set_in_shift(&c, false, true, 8);
sm_config_set_in_shift(&c, false, false, 8);
sm_config_set_in_pins(&c, dataPin);
sm_config_set_sideset_pins(&c, clkPin);
sm_config_set_clkdiv(&c, clkDiv);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
pio_sm_set_consecutive_pindirs(pio, sm, dataPin, 1, false);
pio_sm_set_consecutive_pindirs(pio, sm, clkPin, 1, true);
pio_sm_set_pins_with_mask(pio, sm, 0, (1u << clkPin) );
//pio_gpio_init(pio, dataPin);
pio_gpio_init(pio, clkPin);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
pio_sm_config c = pdm_pio_program_get_default_config(offset);
sm_config_set_sideset(&c, 1, false, false);
//sm_config_set_in_shift(&c, false, true, 8);
sm_config_set_in_shift(&c, false, false, 8);
sm_config_set_in_pins(&c, dataPin);
sm_config_set_sideset_pins(&c, clkPin);
sm_config_set_clkdiv(&c, clkDiv);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
pio_sm_set_consecutive_pindirs(pio, sm, dataPin, 1, false);
pio_sm_set_consecutive_pindirs(pio, sm, clkPin, 1, true);
pio_sm_set_pins_with_mask(pio, sm, 0, (1u << clkPin));
//pio_gpio_init(pio, dataPin);
pio_gpio_init(pio, clkPin);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
#endif

View file

@ -1,19 +1,19 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
Copyright (c) 2016 Arduino LLC. 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 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.
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
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
*/
#include <stdlib.h>
@ -22,118 +22,106 @@
#include "PDMDoubleBuffer.h"
PDMDoubleBuffer::PDMDoubleBuffer() :
_size(DEFAULT_PDM_BUFFER_SIZE)
{
reset();
_size(DEFAULT_PDM_BUFFER_SIZE) {
reset();
}
PDMDoubleBuffer::~PDMDoubleBuffer()
{
PDMDoubleBuffer::~PDMDoubleBuffer() {
}
void PDMDoubleBuffer::setSize(int size)
{
_size = size;
reset();
void PDMDoubleBuffer::setSize(int size) {
_size = size;
reset();
}
size_t PDMDoubleBuffer::getSize()
{
return _size;
size_t PDMDoubleBuffer::getSize() {
return _size;
}
void PDMDoubleBuffer::reset()
{
_buffer[0] = (uint8_t*)realloc(_buffer[0], _size);
_buffer[1] = (uint8_t*)realloc(_buffer[1], _size);
void PDMDoubleBuffer::reset() {
_buffer[0] = (uint8_t*)realloc(_buffer[0], _size);
_buffer[1] = (uint8_t*)realloc(_buffer[1], _size);
memset(_buffer[0], 0x00, _size);
memset(_buffer[1], 0x00, _size);
memset(_buffer[0], 0x00, _size);
memset(_buffer[1], 0x00, _size);
_index = 0;
_length[0] = 0;
_length[1] = 0;
_readOffset[0] = 0;
_readOffset[1] = 0;
}
size_t PDMDoubleBuffer::availableForWrite()
{
return (_size - (_length[_index] - _readOffset[_index]));
}
size_t PDMDoubleBuffer::write(const void *buffer, size_t size)
{
size_t space = availableForWrite();
if (size > space) {
size = space;
}
if (size == 0) {
return 0;
}
memcpy(&_buffer[_index][_length[_index]], buffer, size);
_length[_index] += size;
return size;
}
size_t PDMDoubleBuffer::read(void *buffer, size_t size)
{
size_t avail = available();
if (size > avail) {
size = avail;
}
if (size == 0) {
return 0;
}
memcpy(buffer, &_buffer[_index][_readOffset[_index]], size);
_readOffset[_index] += size;
return size;
}
size_t PDMDoubleBuffer::peek(void *buffer, size_t size)
{
size_t avail = available();
if (size > avail) {
size = avail;
}
if (size == 0) {
return 0;
}
memcpy(buffer, &_buffer[_index][_readOffset[_index]], size);
return size;
}
void* PDMDoubleBuffer::data()
{
return (void*)_buffer[_index];
}
size_t PDMDoubleBuffer::available()
{
return _length[_index] - _readOffset[_index];
}
void PDMDoubleBuffer::swap(int length)
{
if (_index == 0) {
_index = 1;
} else {
_index = 0;
}
_length[_index] = length;
_readOffset[_index] = 0;
_length[0] = 0;
_length[1] = 0;
_readOffset[0] = 0;
_readOffset[1] = 0;
}
size_t PDMDoubleBuffer::availableForWrite() {
return (_size - (_length[_index] - _readOffset[_index]));
}
size_t PDMDoubleBuffer::write(const void *buffer, size_t size) {
size_t space = availableForWrite();
if (size > space) {
size = space;
}
if (size == 0) {
return 0;
}
memcpy(&_buffer[_index][_length[_index]], buffer, size);
_length[_index] += size;
return size;
}
size_t PDMDoubleBuffer::read(void *buffer, size_t size) {
size_t avail = available();
if (size > avail) {
size = avail;
}
if (size == 0) {
return 0;
}
memcpy(buffer, &_buffer[_index][_readOffset[_index]], size);
_readOffset[_index] += size;
return size;
}
size_t PDMDoubleBuffer::peek(void *buffer, size_t size) {
size_t avail = available();
if (size > avail) {
size = avail;
}
if (size == 0) {
return 0;
}
memcpy(buffer, &_buffer[_index][_readOffset[_index]], size);
return size;
}
void* PDMDoubleBuffer::data() {
return (void*)_buffer[_index];
}
size_t PDMDoubleBuffer::available() {
return _length[_index] - _readOffset[_index];
}
void PDMDoubleBuffer::swap(int length) {
if (_index == 0) {
_index = 1;
} else {
_index = 0;
}
_length[_index] = length;
_readOffset[_index] = 0;
}

View file

@ -1,19 +1,19 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
Copyright (c) 2016 Arduino LLC. 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 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.
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
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 _PDM_DOUBLE_BUFFER_H_INCLUDED
@ -24,31 +24,30 @@
#define DEFAULT_PDM_BUFFER_SIZE 512
class PDMDoubleBuffer
{
class PDMDoubleBuffer {
public:
PDMDoubleBuffer();
virtual ~PDMDoubleBuffer();
PDMDoubleBuffer();
virtual ~PDMDoubleBuffer();
void setSize(int size);
size_t getSize();
void setSize(int size);
size_t getSize();
void reset();
void reset();
size_t availableForWrite();
size_t write(const void *buffer, size_t size);
size_t read(void *buffer, size_t size);
size_t peek(void *buffer, size_t size);
void* data();
size_t available();
void swap(int length = 0);
size_t availableForWrite();
size_t write(const void *buffer, size_t size);
size_t read(void *buffer, size_t size);
size_t peek(void *buffer, size_t size);
void* data();
size_t available();
void swap(int length = 0);
private:
uint8_t* _buffer[2] __attribute__((aligned (16)));
int _size;
volatile int _length[2];
volatile int _readOffset[2];
volatile int _index;
uint8_t* _buffer[2] __attribute__((aligned(16)));
int _size;
volatile int _length[2];
volatile int _readOffset[2];
volatile int _index;
};
#endif

View file

@ -17,8 +17,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __SD_H__
#define __SD_H__
#pragma once
#include <Arduino.h>
#include <FS.h>
@ -218,5 +217,3 @@ static inline uint8_t FAT_SECOND(uint16_t fatTime) {
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SD)
extern SDClass SD;
#endif
#endif

View file

@ -1,6 +1,3 @@
#ifndef SDFS_H
#define SDFS_H
/*
SDFS.h - file system wrapper for SdLib
Copyright (c) 2019 Earle F. Philhower, III. All rights reserved.
@ -27,6 +24,9 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <limits>
#include <assert.h>
#include "FS.h"
@ -508,5 +508,3 @@ protected:
extern FS SDFS;
using sdfs::SDFSConfig;
#endif
#endif // SDFS.h

View file

@ -37,8 +37,7 @@
detach() - Stops an attached servos from pulsing its i/o pin.
*/
#ifndef Servo_h
#define Servo_h
#pragma once
#include <Arduino.h>
#include <hardware/pio.h>
@ -89,5 +88,3 @@ private:
};
#endif

View file

@ -1,3 +1,22 @@
/*
StackThunk - Implements a simple 2nd stack for BSSL and others
Copyright (c) 2022 Earle F. Philhower, III. All rights 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
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

View file

@ -1,3 +1,22 @@
/*
StackThunk - Implements a simple 2nd stack for BSSL and others
Copyright (c) 2022 Earle F. Philhower, III. All rights 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
*/
#pragma once
#include <stdint.h>

View file

@ -72,8 +72,7 @@
}
*/
#ifndef __ADDRLIST_H
#define __ADDRLIST_H
#pragma once
#include <IPAddress.h>
#include <api/String.h>
@ -254,6 +253,3 @@ inline AddressList::const_iterator end(const AddressList& a) {
} // esp8266
extern esp8266::AddressListImplementation::AddressList addrList;
#endif

View file

@ -1,3 +1,25 @@
/*
LwipEthernet.h
Arduino interface for lwIP generic callbacks and functions
Original Copyright (c) 2020 esp8266 Arduino All rights 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
*/
//#include <ESP8266WiFi.h> // tcp API
//#include <debug.h>

View file

@ -3,12 +3,12 @@
for dir in ./cores/rp2040 ./libraries/EEPROM ./libraries/I2S \
./libraries/LittleFS/src ./libraries/LittleFS/examples \
./libraries/rp2040 ./libraries/SD ./libraries/ESP8266SdFat \
./libraries/Servo ./libraries/SPI ./libraries/Wire \
./libraries/Servo ./libraries/SPI ./libraries/Wire ./libraries/PDM \
./libraries/WiFi ./libraries/lwIP_Ethernet ./libraries/lwIP_CYW43 \
./libraries/FreeRTOS/src ./libraries/LEAmDNS ./libraries/MD5Builder \
./libraries/PicoOTA ./libraries/SDFS ./libraries/ArduinoOTA \
./libraries/Updater ./libraries/HTTPClient ./libraries/HTTPUpdate \
./libraries/WebServer ./libraries/HTTPUpdateServer ; do
./libraries/WebServer ./libraries/HTTPUpdateServer ./libraries/DNSServer ; do
find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" \) -a \! -path '*api*' -exec astyle --suffix=none --options=./tests/astyle_core.conf \{\} \;
find $dir -type f -name "*.ino" -exec astyle --suffix=none --options=./tests/astyle_examples.conf \{\} \;
done