Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Arduino-Pico RP2040 #193

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name=ESP AsyncTCP
version=1.2.2
version=1.2.3
author=Me-No-Dev
maintainer=Me-No-Dev
sentence=Async TCP Library for ESP8266 and ESP31B
paragraph=Async TCP Library for ESP8266 and ESP31B
sentence=Async TCP Library for ESP8266 and ESP31B and RP2040 Pico
paragraph=Async TCP Library for ESP8266 and ESP31B and RP2040 Pico
category=Other
url=https://github.com/me-no-dev/ESPAsyncTCP
architectures=*
26 changes: 25 additions & 1 deletion src/AsyncPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ AsyncPrinter::AsyncPrinter(AsyncClient *client, size_t txBufLen)
_attachCallbacks();
_tx_buffer = new (std::nothrow) cbuf(_tx_buffer_size);
if(_tx_buffer == NULL) {
#if defined(ARDUINO_ARCH_RP2040)
panic("OOM"); //What should we do?
#else
panic(); //What should we do?
#endif
}
}

Expand All @@ -68,7 +72,11 @@ int AsyncPrinter::connect(IPAddress ip, uint16_t port){
return 0;
_client = new (std::nothrow) AsyncClient();
if (_client == NULL) {
#if defined(ARDUINO_ARCH_RP2040)
panic("OOM");
#else
panic();
#endif
}

_client->onConnect([](void *obj, AsyncClient *c){ ((AsyncPrinter*)(obj))->_onConnect(c); }, this);
Expand All @@ -85,7 +93,11 @@ int AsyncPrinter::connect(const char *host, uint16_t port){
return 0;
_client = new (std::nothrow) AsyncClient();
if (_client == NULL) {
#if defined(ARDUINO_ARCH_RP2040)
panic("OOM");
#else
panic();
#endif
}

_client->onConnect([](void *obj, AsyncClient *c){ ((AsyncPrinter*)(obj))->_onConnect(c); }, this);
Expand All @@ -106,7 +118,11 @@ void AsyncPrinter::_onConnect(AsyncClient *c){
}
_tx_buffer = new (std::nothrow) cbuf(_tx_buffer_size);
if(_tx_buffer) {
#if defined(ARDUINO_ARCH_RP2040)
panic("OOM");
#else
panic();
#endif
}

_attachCallbacks();
Expand All @@ -127,7 +143,11 @@ AsyncPrinter & AsyncPrinter::operator=(const AsyncPrinter &other){
}
_tx_buffer = new (std::nothrow) cbuf(other._tx_buffer_size);
if(_tx_buffer == NULL) {
#if defined(ARDUINO_ARCH_RP2040)
panic("OOM");
#else
panic();
#endif
}

_client = other._client;
Expand Down Expand Up @@ -179,12 +199,16 @@ size_t AsyncPrinter::_sendBuffer(){
available= sendable;
char *out = new (std::nothrow) char[available];
if (out == NULL) {
#if defined(ARDUINO_ARCH_RP2040)
panic("OOM"); // Connection should be aborted instead
#else
panic(); // Connection should be aborted instead
#endif
}

_tx_buffer->read(out, available);
size_t sent = _client->write(out, available);
delete out;
delete[] out;
return sent;
}

Expand Down
2 changes: 2 additions & 0 deletions src/ESPAsyncTCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,8 @@ void AsyncClient::_dns_found(const ip_addr *ipaddr){
if(ipaddr){
#if ASYNC_TCP_SSL_ENABLED
connect(IPAddress(ipaddr->addr), _connect_port, _pcb_secure);
#elif defined(ARDUINO_ARCH_RP2040)
connect(IPAddress((const ip_addr_t*)ipaddr), _connect_port);
#else
connect(IPAddress(ipaddr->addr), _connect_port);
#endif
Expand Down
26 changes: 22 additions & 4 deletions src/ESPAsyncTCPbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,21 @@


#include <Arduino.h>
#if !defined(ARDUINO_ARCH_RP2040)
#include <debug.h>
#endif

#include "ESPAsyncTCPbuffer.h"


AsyncTCPbuffer::AsyncTCPbuffer(AsyncClient* client) {
if(client == NULL) {
DEBUG_ASYNC_TCP("[A-TCP] client is null!!!\n");
#if defined(ARDUINO_ARCH_RP2040)
panic("[A-TCP] client is null!!!\n");
#else
panic();
#endif
}

_client = client;
Expand Down Expand Up @@ -116,15 +122,23 @@ size_t AsyncTCPbuffer::write(const uint8_t *data, size_t len) {
if(_TXbufferWrite->full() && bytesLeft > 0) {

// to less ram!!!
#if defined(ARDUINO_ARCH_RP2040)
if(rp2040.getFreeHeap() < 4096) {
#else
if(ESP.getFreeHeap() < 4096) {
#endif
DEBUG_ASYNC_TCP("[A-TCP] run out of Heap can not send all Data!\n");
return (len - bytesLeft);
}

cbuf * next = new (std::nothrow) cbuf(TCP_MSS);
if(next == NULL) {
DEBUG_ASYNC_TCP("[A-TCP] run out of Heap!\n");
#if defined(ARDUINO_ARCH_RP2040)
panic("[A-TCP] run out of Heap!\n");
#else
panic();
#endif
} else {
DEBUG_ASYNC_TCP("[A-TCP] new cbuf\n");
}
Expand Down Expand Up @@ -221,7 +235,7 @@ void AsyncTCPbuffer::onDisconnect(AsyncTCPbufferDisconnectCb cb) {

IPAddress AsyncTCPbuffer::remoteIP() {
if(!_client) {
return IPAddress(0U);
return IPAddress((uint32_t)0);
}
return _client->remoteIP();
}
Expand Down Expand Up @@ -371,11 +385,11 @@ void AsyncTCPbuffer::_sendBuffer() {
if(_TXbufferRead->available() == 0 && _TXbufferRead->next != NULL) {
cbuf * old = _TXbufferRead;
_TXbufferRead = _TXbufferRead->next;
delete old;
delete[] old;
DEBUG_ASYNC_TCP("[A-TCP] delete cbuf\n");
}

delete out;
delete[] out;
}

}
Expand Down Expand Up @@ -466,8 +480,12 @@ size_t AsyncTCPbuffer::_handleRxBuffer(uint8_t *buf, size_t len) {
if(BufferAvailable > 0) {
uint8_t * b = new (std::nothrow) uint8_t[BufferAvailable];
if(b == NULL){
#if defined(ARDUINO_ARCH_RP2040)
panic("OOM"); //TODO: What action should this be ?
#else
panic(); //TODO: What action should this be ?
}
#endif
}
_RXbuffer->peek((char *) b, BufferAvailable);
r = _cbRX(b, BufferAvailable);
_RXbuffer->remove(r);
Expand Down
2 changes: 2 additions & 0 deletions src/SyncClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
#include "SyncClient.h"
#include "ESPAsyncTCP.h"
#include "cbuf.h"
#if !defined(ARDUINO_ARCH_RP2040)
#include <interrupts.h>
#endif

#define DEBUG_ESP_SYNC_CLIENT
#if defined(DEBUG_ESP_SYNC_CLIENT) && !defined(SYNC_CLIENT_DEBUG)
Expand Down
184 changes: 184 additions & 0 deletions src/cbuf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#if defined(ARDUINO_ARCH_RP2040)
/*
cbuf.cpp - Circular buffer implementation
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.

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 <new> // std::nothrow
#include "cbuf.h"
//#include "c_types.h"
#undef IRAM_ATTR
#define IRAM_ATTR

cbuf::cbuf(size_t size) :
next(NULL), _size(size), _buf(new char[size]), _bufend(_buf + size), _begin(_buf), _end(_begin) {
}

cbuf::~cbuf() {
delete[] _buf;
}

size_t cbuf::resizeAdd(size_t addSize) {
return resize(_size + addSize);
}

size_t cbuf::resize(size_t newSize) {

size_t bytes_available = available();

// not lose any data
// if data can be lost use remove or flush before resize
if((newSize <= bytes_available) || (newSize == _size)) {
return _size;
}

char *newbuf = new (std::nothrow) char[newSize];
char *oldbuf = _buf;

if(!newbuf) {
return _size;
}

if(_buf) {
read(newbuf, bytes_available);
memset((newbuf + bytes_available), 0x00, (newSize - bytes_available));
}

_begin = newbuf;
_end = newbuf + bytes_available;
_bufend = newbuf + newSize;
_size = newSize;

_buf = newbuf;
delete[] oldbuf;

return _size;
}

size_t IRAM_ATTR cbuf::available() const {
if(_end >= _begin) {
return _end - _begin;
}
return _size - (_begin - _end);
}

size_t cbuf::size() {
return _size;
}

size_t cbuf::room() const {
if(_end >= _begin) {
return _size - (_end - _begin) - 1;
}
return _begin - _end - 1;
}

int cbuf::peek() {
if(empty())
return -1;

return static_cast<int>(*_begin);
}

size_t cbuf::peek(char *dst, size_t size) {
size_t bytes_available = available();
size_t size_to_read = (size < bytes_available) ? size : bytes_available;
size_t size_read = size_to_read;
char * begin = _begin;
if(_end < _begin && size_to_read > (size_t) (_bufend - _begin)) {
size_t top_size = _bufend - _begin;
memcpy(dst, _begin, top_size);
begin = _buf;
size_to_read -= top_size;
dst += top_size;
}
memcpy(dst, begin, size_to_read);
return size_read;
}

int IRAM_ATTR cbuf::read() {
if(empty())
return -1;

char result = *_begin;
_begin = wrap_if_bufend(_begin + 1);
return static_cast<int>(result);
}

size_t cbuf::read(char* dst, size_t size) {
size_t bytes_available = available();
size_t size_to_read = (size < bytes_available) ? size : bytes_available;
size_t size_read = size_to_read;
if(_end < _begin && size_to_read > (size_t) (_bufend - _begin)) {
size_t top_size = _bufend - _begin;
memcpy(dst, _begin, top_size);
_begin = _buf;
size_to_read -= top_size;
dst += top_size;
}
memcpy(dst, _begin, size_to_read);
_begin = wrap_if_bufend(_begin + size_to_read);
return size_read;
}

size_t IRAM_ATTR cbuf::write(char c) {
if(full())
return 0;

*_end = c;
_end = wrap_if_bufend(_end + 1);
return 1;
}

size_t cbuf::write(const char* src, size_t size) {
size_t bytes_available = room();
size_t size_to_write = (size < bytes_available) ? size : bytes_available;
size_t size_written = size_to_write;
if(_end >= _begin && size_to_write > (size_t) (_bufend - _end)) {
size_t top_size = _bufend - _end;
memcpy(_end, src, top_size);
_end = _buf;
size_to_write -= top_size;
src += top_size;
}
memcpy(_end, src, size_to_write);
_end = wrap_if_bufend(_end + size_to_write);
return size_written;
}

void cbuf::flush() {
_begin = _buf;
_end = _buf;
}

size_t cbuf::remove(size_t size) {
size_t bytes_available = available();
if(size >= bytes_available) {
flush();
return 0;
}
size_t size_to_remove = (size < bytes_available) ? size : bytes_available;
if(_end < _begin && size_to_remove > (size_t) (_bufend - _begin)) {
size_t top_size = _bufend - _begin;
_begin = _buf;
size_to_remove -= top_size;
}
_begin = wrap_if_bufend(_begin + size_to_remove);
return available();
}
#endif
Loading