many changes :Py
This commit is contained in:
2
Debug.h
2
Debug.h
@@ -42,7 +42,7 @@ void hexdump(const uint8_t* buf, uint8_t len) {
|
||||
|
||||
#else
|
||||
|
||||
#define debug(module, str)
|
||||
#define debug(str)
|
||||
#define debugMod(module, str)
|
||||
#define debugMod1(module, str, val)
|
||||
#define debugMod2(module, str, v1, v2)
|
||||
|
||||
12
Platforms.h
Normal file
12
Platforms.h
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
#define WEMOS_D1_MINI 1
|
||||
#define NODE_MCU 2
|
||||
|
||||
|
||||
// https://blog.anto.io/wp-content/uploads/2016/12/esp32.png
|
||||
#define NODE32S 32
|
||||
|
||||
|
||||
|
||||
#define PLATFORM NODE32S
|
||||
53
c++.h
53
c++.h
@@ -4,7 +4,11 @@
|
||||
#define FALSE false
|
||||
|
||||
typedef void (*int_handler_t)(void*);
|
||||
/*
|
||||
|
||||
// ONLY NEEDED FOR OLD SDK <= 2.0.0
|
||||
//#define OLD_SDK
|
||||
#ifdef OLD_SDK
|
||||
|
||||
void *pvPortMalloc(size_t xWantedSize, const char* file, int line) __attribute__((malloc, alloc_size(1)));
|
||||
void *pvPortRealloc(void* ptr, size_t xWantedSize, const char* file, int line) __attribute__((alloc_size(2)));
|
||||
void vPortFree(void *ptr, const char* file, int line);
|
||||
@@ -98,17 +102,14 @@ inline uint32_t ETS_INTR_PENDING(void)
|
||||
#define ETS_CCOMPARE0_DISABLE() \
|
||||
ETS_INTR_DISABLE(ETS_CCOMPARE0_INUM)
|
||||
|
||||
|
||||
//#define ETS_FRC_TIMER1_INTR_ATTACH(func, arg) \
|
||||
// ets_isr_attach(ETS_FRC_TIMER1_INUM, (int_handler_t)(func), (void *)(arg))
|
||||
//#define ETS_FRC_TIMER1_INTR_ATTACH(func, arg) ets_isr_attach(ETS_FRC_TIMER1_INUM, (int_handler_t)(func), (void *)(arg))
|
||||
|
||||
|
||||
#define ETS_FRC_TIMER1_NMI_INTR_ATTACH(func) \
|
||||
NmiTimSetFunc(func)
|
||||
|
||||
|
||||
//#define ETS_GPIO_INTR_ATTACH(func, arg) \
|
||||
// ets_isr_attach(ETS_GPIO_INUM, (int_handler_t)(func), (void *)(arg))
|
||||
//#define ETS_GPIO_INTR_ATTACH(func, arg) ets_isr_attach(ETS_GPIO_INUM, (int_handler_t)(func), (void *)(arg))
|
||||
|
||||
|
||||
#define ETS_GPIO_INTR_ENABLE() \
|
||||
@@ -118,8 +119,7 @@ inline uint32_t ETS_INTR_PENDING(void)
|
||||
ETS_INTR_DISABLE(ETS_GPIO_INUM)
|
||||
|
||||
|
||||
//#define ETS_UART_INTR_ATTACH(func, arg) \
|
||||
// ets_isr_attach(ETS_UART_INUM, (int_handler_t)(func), (void *)(arg))
|
||||
//#define ETS_UART_INTR_ATTACH(func, arg) ets_isr_attach(ETS_UART_INUM, (int_handler_t)(func), (void *)(arg))
|
||||
|
||||
|
||||
#define ETS_UART_INTR_ENABLE() \
|
||||
@@ -135,8 +135,7 @@ inline uint32_t ETS_INTR_PENDING(void)
|
||||
ETS_INTR_DISABLE(ETS_FRC_TIMER1_INUM)
|
||||
|
||||
|
||||
//#define ETS_SPI_INTR_ATTACH(func, arg) \
|
||||
// ets_isr_attach(ETS_SPI_INUM, (int_handler_t)(func), (void *)(arg))
|
||||
//#define ETS_SPI_INTR_ATTACH(func, arg) ets_isr_attach(ETS_SPI_INUM, (int_handler_t)(func), (void *)(arg))
|
||||
|
||||
|
||||
#define ETS_SPI_INTR_ENABLE() \
|
||||
@@ -156,8 +155,7 @@ inline uint32_t ETS_INTR_PENDING(void)
|
||||
ETS_INTR_DISABLE(ETS_SLC_INUM)
|
||||
|
||||
|
||||
//#define ETS_SDIO_INTR_ATTACH(func, arg) \
|
||||
// ets_isr_attach(ETS_SDIO_INUM, (int_handler_t)(func), (void *)(arg))
|
||||
//#define ETS_SDIO_INTR_ATTACH(func, arg) ets_isr_attach(ETS_SDIO_INUM, (int_handler_t)(func), (void *)(arg))
|
||||
|
||||
#define ETS_SDIO_INTR_ENABLE() \
|
||||
ETS_INTR_ENABLE(ETS_SDIO_INUM)
|
||||
@@ -183,7 +181,31 @@ extern void ets_delay_us(uint32_t us);
|
||||
extern int os_printf_plus(const char * format, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
void* malloc(size_t size) {
|
||||
return os_malloc(size);
|
||||
}
|
||||
void free(void* ptr) {
|
||||
os_free(ptr);
|
||||
}
|
||||
|
||||
|
||||
void operator delete(void* ptr) {
|
||||
os_free(ptr);
|
||||
}
|
||||
|
||||
void* operator new(size_t size) {
|
||||
return os_malloc(size);
|
||||
}
|
||||
|
||||
/** missing within headers?! */
|
||||
int ipaddr_aton(const char *cp, ip_addr_t *addr)ICACHE_FLASH_ATTR;
|
||||
char *ipaddr_ntoa(const ip_addr_t *addr);
|
||||
|
||||
|
||||
//void run_sdk_tasks();
|
||||
|
||||
/*
|
||||
bool wifi_station_get_config(struct station_config *config);
|
||||
@@ -281,6 +303,7 @@ bool wifi_set_phy_mode(phy_mode_t mode);
|
||||
|
||||
// ensure constructors are called
|
||||
// See more at: http://www.esp8266.com/viewtopic.php?f=9&t=478&start=8#sthash.uVL8shrS.dpuf
|
||||
// https://www.esp8266.com/viewtopic.php?f=9&t=478&sid=4375c81b073ef125fb57ab2fc3b38041&start=8
|
||||
// SEE NOTES BELOW!!!
|
||||
extern void (*__init_array_start)(void);
|
||||
extern void (*__init_array_end)(void);
|
||||
@@ -295,3 +318,7 @@ static void do_global_ctors(void) {
|
||||
}
|
||||
|
||||
|
||||
// memory stuff
|
||||
// https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map
|
||||
|
||||
|
||||
|
||||
193
data/ChunkBuffer.h
Normal file
193
data/ChunkBuffer.h
Normal file
@@ -0,0 +1,193 @@
|
||||
#ifndef CHUNK_BUFFER_H
|
||||
#define CHUNK_BUFFER_H
|
||||
|
||||
#include "../Debug.h"
|
||||
|
||||
/**
|
||||
* linked list of several chunks that are either managed or unmanaged
|
||||
*/
|
||||
class ChunkBuffer {
|
||||
|
||||
public:
|
||||
|
||||
/** data of certain length */
|
||||
struct Data {
|
||||
const uint8_t* ptr;
|
||||
const uint16_t size;
|
||||
Data(const uint8_t* ptr, const uint16_t size) : ptr(ptr), size(size) {;}
|
||||
};
|
||||
|
||||
/** one data chunk within the buffer */
|
||||
struct Chunk {
|
||||
|
||||
bool managed;
|
||||
uint8_t* base; // do not modify this one!
|
||||
|
||||
uint8_t* ptr;
|
||||
uint16_t len;
|
||||
|
||||
Chunk* next = nullptr;
|
||||
|
||||
~Chunk() {
|
||||
debugMod("ChunkBuffer::Chunk", "dtor");
|
||||
if (managed) {
|
||||
free(base);
|
||||
base = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/** allocate a new managed chunk */
|
||||
static Chunk* alloc(const uint16_t size) {
|
||||
debugMod1("ChunkBuffer::Chunk", "alloc(%d)", size);
|
||||
Chunk* chunk = new Chunk();
|
||||
chunk->base = (uint8_t*)malloc(size);
|
||||
chunk->ptr = chunk->base;
|
||||
chunk->len = size;
|
||||
chunk->managed = true;
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/** allocate a new wrapped chunk */
|
||||
static Chunk* wrap(uint8_t* ptr, const uint16_t size) {
|
||||
debugMod1("ChunkBuffer::Chunk", "alloc(%d)", size);
|
||||
Chunk* chunk = new Chunk();
|
||||
chunk->base = ptr;
|
||||
chunk->ptr = chunk->base;
|
||||
chunk->len = size;
|
||||
chunk->managed = false;
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/** consume max(!) size bytes from this chunk */
|
||||
Data consume(const uint16_t size) {
|
||||
debugMod1("ChunkBuffer::Chunk", "consume(%d)", size);
|
||||
const uint16_t useBytes = min(size, this->len);
|
||||
Data res(ptr, useBytes);
|
||||
ptr += useBytes; // adjust pointer for next consume() call
|
||||
len -= useBytes; // adjuste len for next consume() call;
|
||||
return res;
|
||||
}
|
||||
|
||||
/** consume one byte, if available */
|
||||
int consumeByte() {
|
||||
if (len) {
|
||||
uint8_t res = *ptr;
|
||||
ptr += 1;
|
||||
len -= 1;
|
||||
return res;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return len == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
Chunk() {;}
|
||||
|
||||
};
|
||||
|
||||
static uint16_t min(const uint16_t a, const uint16_t b) {
|
||||
return (a<b) ? (a) : (b);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Chunk* root;
|
||||
|
||||
public:
|
||||
|
||||
ChunkBuffer() : root(nullptr) {
|
||||
debugMod("ChunkBuffer", "ctor()");
|
||||
}
|
||||
|
||||
/** get a block of max(!) size bytes from the buffer. might return less */
|
||||
Data get(const uint16_t size) {
|
||||
|
||||
cleanup();
|
||||
|
||||
// something available?
|
||||
if (!root) {
|
||||
return Data(0,0);
|
||||
} else {
|
||||
return root->consume(size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int getByte() {
|
||||
|
||||
cleanup();
|
||||
|
||||
if (root && !root->empty()) {
|
||||
return root->consumeByte();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** append the given chunk to the buffer */
|
||||
void append(Chunk* c) {
|
||||
|
||||
debugMod("ChunkBuffer", "append()");
|
||||
|
||||
if (!root) {
|
||||
|
||||
// new chunk is the root
|
||||
root = c;
|
||||
|
||||
} else {
|
||||
|
||||
// append new chunk at the end
|
||||
Chunk* x = root;
|
||||
while (x->next) {x = x->next;}
|
||||
x->next = c;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** allocate a new managed chunk of the given size */
|
||||
Chunk* alloc(const uint16_t size) {
|
||||
debugMod1("ChunkBuffer", "alloc(%d)", size);
|
||||
return Chunk::alloc(size);
|
||||
}
|
||||
|
||||
/** get a new unmanaged wrapper chunk for the given data */
|
||||
Chunk* wrap(const uint8_t* data, const uint16_t size) {
|
||||
debugMod1("ChunkBuffer", "wrap(%d)", size);
|
||||
return Chunk::wrap((uint8_t*) data, size);
|
||||
}
|
||||
|
||||
/** number of available bytes */
|
||||
uint32_t available() const {
|
||||
uint32_t s = 0;
|
||||
Chunk* c = root;
|
||||
while(c) {
|
||||
s += c->len;
|
||||
c = c->next;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/** nothing available? */
|
||||
bool empty() const {
|
||||
return (!root || root->len == 0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void cleanup() {
|
||||
|
||||
// current chunk empty? -> cleanup and proceed with next chunk
|
||||
if (root && root->empty()) {
|
||||
Chunk* old = root;
|
||||
root = old->next; // next chunk is the chunk (if any) after the current (empty) one
|
||||
delete old; // delete the empty chunk and free the data
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // CHUNK_BUFFER_H
|
||||
@@ -1,56 +1,97 @@
|
||||
#ifndef RINGBUFFER_H
|
||||
#define RINGBUFFER_H
|
||||
|
||||
#include "../Debug.h"
|
||||
|
||||
typedef void (*RingBufferFullCallback)();
|
||||
|
||||
|
||||
template <typename Scalar, int size> class RingBuffer {
|
||||
|
||||
private:
|
||||
|
||||
static constexpr const char* NAME = "RingBuffer";
|
||||
|
||||
Scalar data[size];
|
||||
|
||||
volatile size_t head;
|
||||
volatile size_t tail;
|
||||
volatile size_t used;
|
||||
volatile mutable size_t used;
|
||||
|
||||
public:
|
||||
|
||||
RingBuffer() {
|
||||
init();
|
||||
}
|
||||
|
||||
void init() {
|
||||
head = 0;
|
||||
tail = 0;
|
||||
used = 0;
|
||||
}
|
||||
|
||||
/** add one value to the buffer */
|
||||
void clear() {
|
||||
init();
|
||||
}
|
||||
|
||||
/** add one value to the buffer. blocks until space is available */
|
||||
void addBlocking(const Scalar value) {
|
||||
|
||||
while (used == size) {os_delay_us(1000);}
|
||||
|
||||
data[head] = value;
|
||||
head = (head + 1) % size;
|
||||
++used;
|
||||
}
|
||||
|
||||
/** add one value to the buffer */
|
||||
void addIgnore(const Scalar value) {
|
||||
|
||||
/** add one value to the buffer, if there is enough space */
|
||||
void addOrIgnore(const Scalar value) {
|
||||
if (used == size) {return;}
|
||||
|
||||
data[head] = value;
|
||||
head = (head + 1) % size;
|
||||
++used;
|
||||
}
|
||||
|
||||
/** add multiple values to the buffer */
|
||||
void add(const Scalar* value, const size_t len) {
|
||||
/** add one value to the buffer, or call the callback if there is no space available */
|
||||
void addOrCallback(const Scalar value, RingBufferFullCallback cb) {
|
||||
while(used == size) {cb();}
|
||||
data[head] = value;
|
||||
head = (head + 1) % size;
|
||||
++used;
|
||||
}
|
||||
|
||||
|
||||
/** add multiple values to the buffer. blocks until space is available */
|
||||
void addBlocking(const Scalar* value, const size_t len) {
|
||||
debugMod1(NAME, "addBlocking(%d)", len);
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
add(value[i]);
|
||||
addBlocking(value[i]);
|
||||
}
|
||||
debugMod1(NAME, "used: %d", used);
|
||||
}
|
||||
|
||||
/** anything available? */
|
||||
bool hasNext() const {
|
||||
return used != 0;
|
||||
/** add multiple values to the buffer, if there is enough space */
|
||||
void addOrIgnore(const Scalar* value, const size_t len) {
|
||||
debugMod1(NAME, "addOrIgnore(%d)", len);
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
addOrIgnore(value[i]);
|
||||
}
|
||||
debugMod1(NAME, "used: %d", used);
|
||||
}
|
||||
|
||||
/** add multiple values to the buffer, if there is enough space */
|
||||
void addOrCallback(const Scalar* value, const size_t len, RingBufferFullCallback cb) {
|
||||
debugMod1(NAME, "addOrCallback(%d)", len);
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
addOrCallback(value[i], cb);
|
||||
}
|
||||
debugMod1(NAME, "used: %d", used);
|
||||
}
|
||||
|
||||
// /** anything available? */
|
||||
// bool hasNext() const {
|
||||
// return used != 0;
|
||||
// }
|
||||
|
||||
/** get the next value from the buffer */
|
||||
Scalar get() {
|
||||
const Scalar res = data[tail];
|
||||
tail = (tail + 1) % size;
|
||||
@@ -58,22 +99,33 @@ public:
|
||||
return res;
|
||||
}
|
||||
|
||||
const Scalar& getConst() {
|
||||
const Scalar& getConst() const {
|
||||
const uint8_t idx = tail;
|
||||
tail = (tail + 1) % size;
|
||||
--used;
|
||||
return data[idx];
|
||||
}
|
||||
|
||||
// /** true if the buffer is currently empty */
|
||||
// bool isEmpty() const {
|
||||
// return head == tail;
|
||||
// }
|
||||
/** true if the buffer is currently empty */
|
||||
bool empty() const {
|
||||
return used == 0;
|
||||
}
|
||||
|
||||
/** true if the buffer is currently full */
|
||||
bool full() const {
|
||||
return size == used;
|
||||
}
|
||||
|
||||
/** get the number of used elements within the buffer */
|
||||
size_t getNumUsed() const {
|
||||
return used;
|
||||
}
|
||||
|
||||
/** get the number of free elements within the buffer */
|
||||
size_t getNumFree() const {
|
||||
return size-used;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // RINGBUFFER_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef AUDIODATA_H
|
||||
#define AUDIODATA_H
|
||||
|
||||
#define min(a,b) ( (a<b) ? (a) : (b) )
|
||||
|
||||
|
||||
struct Data {
|
||||
const uint8_t* data;
|
||||
@@ -14,6 +14,10 @@ struct AudioData {
|
||||
const uint8_t* data;
|
||||
uint32_t available;
|
||||
|
||||
static uint32_t min(uint32_t a, uint32_t b) {
|
||||
return (a<b) ? (a) : (b);
|
||||
}
|
||||
|
||||
AudioData() : data(nullptr), available(0) {;}
|
||||
|
||||
AudioData(const uint8_t* data, const uint32_t len) : data(data), available(len) {
|
||||
|
||||
@@ -1,34 +1,38 @@
|
||||
#ifndef VS1003_H
|
||||
#define VS1003_H
|
||||
|
||||
#include "io/fastGPIO.h"
|
||||
#include "../io/SoftSPI.h"
|
||||
#include "../../io/fastGPIO.h"
|
||||
#include "../../io/SoftSPI.h"
|
||||
#include "../../Debug.h"
|
||||
//#include "IPlayable.h"
|
||||
#include "AudioData.h"
|
||||
//#include "AudioData.h"
|
||||
#include "../../data/ChunkBuffer.h"
|
||||
|
||||
|
||||
/**
|
||||
* control a VS1003 audio chip attached to the SPI port
|
||||
*/
|
||||
class VS1003 {
|
||||
template <typename PlayBuf> class VS1003 {
|
||||
|
||||
private:
|
||||
|
||||
SoftSPI spi;
|
||||
#define SPI_INIT() spi.init();
|
||||
#define SPI_WRITE_8(byte) spi.writeByte(byte)
|
||||
#define SPI_WRITE_16(word) spi.writeWord(word)
|
||||
#define SPI_READ_8(byte) spi.readByte(byte)
|
||||
#define SPI_READ_16(word) spi.readWord(word)
|
||||
#define SPI_READ_WRITE_8(byte) spi.readWriteByte(byte)
|
||||
#define SPI_READ_WRITE_16(word) spi.readWriteWord(word)
|
||||
static constexpr const char* NAME = "VS1003";
|
||||
|
||||
//SoftSPI spi;
|
||||
#define SPI_INIT() spi::init();
|
||||
#define SPI_WRITE_8(byte) spi::writeByte(byte)
|
||||
#define SPI_WRITE_16(word) spi::writeWord(word)
|
||||
#define SPI_READ_8(byte) spi::readByte(byte)
|
||||
#define SPI_READ_16(word) spi::readWord(word)
|
||||
#define SPI_READ_WRITE_8(byte) spi::readWriteByte(byte)
|
||||
#define SPI_READ_WRITE_16(word) spi::readWriteWord(word)
|
||||
//#define SPI_DELAY() os_delay_us(10)
|
||||
#define SPI_DELAY() //os_delay_us(10)
|
||||
|
||||
#define GET_DREQ() GPIO16_IN // PIN D0
|
||||
|
||||
|
||||
#define MP3_CTRL_DESELECT() spi.chipDeselect();
|
||||
#define MP3_CTRL_SELECT() spi.chipSelect();
|
||||
#define MP3_CTRL_DESELECT() spi::chipDeselect();
|
||||
#define MP3_CTRL_SELECT() spi::chipSelect();
|
||||
#define MP3_DATA_DESELECT() GPIO5_H
|
||||
#define MP3_DATA_SELECT() GPIO5_L
|
||||
|
||||
@@ -92,9 +96,15 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
VS1003() {
|
||||
init();
|
||||
}
|
||||
|
||||
/** initialize the hardware */
|
||||
void init() {
|
||||
|
||||
debugMod(NAME, "init()");
|
||||
|
||||
SPI_INIT();
|
||||
|
||||
GPIO5_OUTPUT_SET; // Pin D1 - XDCS
|
||||
@@ -103,6 +113,7 @@ public:
|
||||
this->state = PlayState::STOPPED;
|
||||
|
||||
awaitDREQ(); // Wait for the VS1003 to finish boot
|
||||
|
||||
reset();
|
||||
|
||||
}
|
||||
@@ -112,6 +123,7 @@ public:
|
||||
* @param Audio volume to set on both channels.
|
||||
*/
|
||||
void setVolume(const uint8_t vol) const {
|
||||
debugMod1(NAME, "setVolume(%d)", vol);
|
||||
const uint8_t aVol = 255 - vol;
|
||||
const uint16_t values = (aVol << 0) | (aVol << 8); // left and right
|
||||
writeRegister(SCI_VOL, values);
|
||||
@@ -122,10 +134,16 @@ public:
|
||||
return (255 - (values & 0xFF));
|
||||
}
|
||||
|
||||
void play(AudioData ad) {
|
||||
this->playable = ad;
|
||||
this->state = PlayState::PLAYING;
|
||||
}
|
||||
// void play(AudioData ad) {
|
||||
// this->playable = ad;
|
||||
// this->state = PlayState::PLAYING;
|
||||
// }
|
||||
|
||||
// void appendUnmanaged(const uint8_t* data, const uint16_t size) {
|
||||
// ChunkBuffer::Chunk* c = playBuf.wrap(data, size);
|
||||
// playBuf.append(c);
|
||||
// this->state = PlayState::PLAYING;
|
||||
// }
|
||||
|
||||
void ICACHE_FLASH_ATTR record(RecordSource source) {
|
||||
|
||||
@@ -164,18 +182,22 @@ public:
|
||||
return this->state;
|
||||
}
|
||||
|
||||
void play() {
|
||||
//if(this->state == PlayState::STOPPED) { reset(); } // makes things more stable
|
||||
this->state = PlayState::PLAYING;
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR run() {
|
||||
if(this->state == PlayState::PLAYING) {
|
||||
if (!playable.isEOF()) {
|
||||
const Data chunk = playable.read(32);
|
||||
playChunk32(chunk.data, chunk.len);
|
||||
if (playBuf.empty()) {
|
||||
//uint8_t stopSequence[4] = {0};
|
||||
//playChunk32(stopSequence, sizeof(stopSequence)); // end of stream
|
||||
//this->state = PlayState::STOPPED;
|
||||
} else {
|
||||
this->state = PlayState::STOPPED;
|
||||
uint8_t stopSequence[4] = {0};
|
||||
playChunk32(stopSequence, sizeof(stopSequence));
|
||||
//const ChunkBuffer::Data chunk = playBuf.get(32);
|
||||
//playChunk32(chunk.ptr, chunk.size);
|
||||
sendPlayBuffer();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,6 +239,16 @@ public:
|
||||
|
||||
}
|
||||
|
||||
PlayBuf& getPlayBuffer() {
|
||||
return playBuf;
|
||||
}
|
||||
|
||||
void stop() {
|
||||
this->state = PlayState::STOPPED;
|
||||
playBuf.clear();
|
||||
//reset();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
uint32_t getNumAvailableRecordBytes() {
|
||||
@@ -224,15 +256,30 @@ private:
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR playChunk32(const uint8_t* buffer, const uint32_t len) const {
|
||||
debugMod1(NAME, "playChunk32() len:%d", len);
|
||||
MP3_CTRL_DESELECT();
|
||||
MP3_DATA_SELECT();
|
||||
awaitDREQ();
|
||||
|
||||
for(uint32_t i = 0; i < len; ++i) {
|
||||
awaitDREQ();
|
||||
SPI_WRITE_8(buffer[i]);
|
||||
}
|
||||
MP3_DATA_DESELECT();
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR sendPlayBuffer() {
|
||||
MP3_CTRL_DESELECT();
|
||||
MP3_DATA_SELECT();
|
||||
int written = 0;
|
||||
while(canConsume() && !playBuf.empty()) {
|
||||
const uint8_t byte = playBuf.get();
|
||||
if (byte == -1) {break;}
|
||||
SPI_WRITE_8(byte);
|
||||
++written;
|
||||
}
|
||||
if (written) {debugMod1(NAME, "sendPlayBuffer(): %d bytes", written);}
|
||||
MP3_DATA_DESELECT();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the given register.
|
||||
@@ -273,7 +320,17 @@ private:
|
||||
* @brief Wait for the VS1003 to set DREQ to high (it wants data).
|
||||
*/
|
||||
inline void awaitDREQ() const {
|
||||
debugMod(NAME, "awaitDREQ()");
|
||||
while(!GET_DREQ()) {;}
|
||||
//debugMod(NAME, "awaitDREQ() complete");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief VS1003 is able do consume data
|
||||
* @return
|
||||
*/
|
||||
inline bool canConsume() const {
|
||||
return GET_DREQ();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,6 +338,9 @@ private:
|
||||
* @param modeMask Additional mask to or into the mode that is written to the VS1003's register.
|
||||
*/
|
||||
void reset(Mode modeMask = Mode::NONE) const {
|
||||
|
||||
debugMod(NAME, "reset()");
|
||||
|
||||
writeRegister(SCI_MODE, (2052 | (uint16_t)modeMask)); // TODO: remove SM_TESTS
|
||||
os_delay_us(1);
|
||||
awaitDREQ();
|
||||
@@ -297,13 +357,17 @@ private:
|
||||
|
||||
os_delay_us(100);
|
||||
MP3_CTRL_DESELECT();
|
||||
|
||||
debugMod(NAME, "reset() complete");
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
//IPlayable* playable = nullptr;
|
||||
AudioData playable;
|
||||
|
||||
PlayState state = PlayState::STOPPED;
|
||||
|
||||
PlayBuf playBuf;
|
||||
|
||||
};
|
||||
|
||||
#endif // VS1003_H
|
||||
|
||||
@@ -97,6 +97,10 @@ public:
|
||||
return Color(r+o.r, g+o.g, b+o.g);
|
||||
}
|
||||
|
||||
Color operator * (const float f) const {
|
||||
return Color(r*f, g*f, b*f);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <int numLEDs> class WS2812B {
|
||||
@@ -117,6 +121,10 @@ template <int numLEDs> class WS2812B {
|
||||
|
||||
/** ctor */
|
||||
WS2812B() {
|
||||
init();
|
||||
}
|
||||
|
||||
void init() {
|
||||
LED_SET_PIN_TO_OUTPUT;
|
||||
}
|
||||
|
||||
@@ -125,11 +133,25 @@ template <int numLEDs> class WS2812B {
|
||||
colors[idx] = rgb;
|
||||
}
|
||||
|
||||
/** set the color for all LEDs */
|
||||
void setColor(const Color rgb) {
|
||||
for (int idx = 0; idx < numLEDs; ++idx) {
|
||||
colors[idx] = rgb;
|
||||
}
|
||||
}
|
||||
|
||||
/** enable/disable the given LED */
|
||||
void setEnabled(const uint8_t idx, const bool en) {
|
||||
enabled[idx] = en;
|
||||
}
|
||||
|
||||
/** enable/disable all LEDs */
|
||||
void setEnabled(const bool en) {
|
||||
for (int idx = 0; idx < numLEDs; ++idx) {
|
||||
enabled[idx] = en;
|
||||
}
|
||||
}
|
||||
|
||||
/** is the given LED enabled? */
|
||||
bool isEnabled(const uint8_t idx) const {
|
||||
return enabled[idx];
|
||||
@@ -140,11 +162,11 @@ template <int numLEDs> class WS2812B {
|
||||
}
|
||||
|
||||
/** flush configured changes */
|
||||
void flush() {
|
||||
void flush() {
|
||||
|
||||
LED_SET_PIN_TO_OUTPUT;
|
||||
|
||||
// cli();
|
||||
ets_intr_lock();
|
||||
|
||||
// process each LED
|
||||
for (uint8_t i = 0; i < numLEDs; ++i) {
|
||||
@@ -163,9 +185,9 @@ template <int numLEDs> class WS2812B {
|
||||
|
||||
}
|
||||
|
||||
reset();
|
||||
ets_intr_unlock();
|
||||
|
||||
//sei();
|
||||
reset();
|
||||
|
||||
}
|
||||
|
||||
|
||||
6
io/IO.h
6
io/IO.h
@@ -1,6 +1,8 @@
|
||||
#ifndef IO_H
|
||||
#define IO_H
|
||||
|
||||
#include "../Platforms.h"
|
||||
|
||||
// http://www.electrodragon.com/w/ESP8266_IoT_Firmware
|
||||
// https://esp8266.ru/esp8266-pin-register-strapping/
|
||||
// http://www.limpkin.fr/index.php?post/2014/12/07/First-Steps-with-the-ESP8266-03-Development-Board
|
||||
@@ -70,8 +72,8 @@ public:
|
||||
GPIO2_OUTPUT_SET;
|
||||
if (on) {GPIO2_H;} else {GPIO2_L;}
|
||||
#elif PLATFORM == NODE_MCU
|
||||
GPIO16_OUTPUT_SET;
|
||||
if (on) {GPIO16_H;} else {GPIO16_L;}
|
||||
//GPIO16_OUTPUT_SET;
|
||||
//if (on) {GPIO16_H;} else {GPIO16_L;}
|
||||
GPIO2_OUTPUT_SET;
|
||||
if (on) {GPIO2_H;} else {GPIO2_L;}
|
||||
#else
|
||||
|
||||
57
io/SoftSPI.h
57
io/SoftSPI.h
@@ -2,27 +2,54 @@
|
||||
#define SOFTSPI_H
|
||||
|
||||
//#include "IO.h"
|
||||
#include "fastGPIO.h"
|
||||
#include "../Platforms.h"
|
||||
|
||||
// wemos D1 mini
|
||||
#define SPI_CS_OUTPUT GPIO15_OUTPUT_SET
|
||||
#define SPI_MOSI_OUTPUT GPIO13_OUTPUT_SET
|
||||
#define SPI_MISO_INPUT GPIO12_INPUT_SET
|
||||
#define SPI_MISO_NO_PULLUP GPIO12_INPUT_PULLUP_UNSET
|
||||
#define SPI_CLK_OUTPUT GPIO14_OUTPUT_SET
|
||||
|
||||
#define SPI_CS_LO GPIO15_L
|
||||
#define SPI_CS_HI GPIO15_H
|
||||
#if (PLATFORM == NODE_MCU) || (PLATFORM == WEMOS_D1_MINI)
|
||||
|
||||
#define SPI_CLK_LO GPIO14_L
|
||||
#define SPI_CLK_HI GPIO14_H
|
||||
#include "fastGPIO.h"
|
||||
|
||||
#define SPI_MOSI_LO GPIO13_L
|
||||
#define SPI_MOSI_HI GPIO13_H
|
||||
#define SPI_CS_OUTPUT GPIO15_OUTPUT_SET
|
||||
#define SPI_MOSI_OUTPUT GPIO13_OUTPUT_SET
|
||||
#define SPI_MISO_INPUT GPIO12_INPUT_SET
|
||||
#define SPI_MISO_NO_PULLUP GPIO12_INPUT_PULLUP_UNSET
|
||||
#define SPI_CLK_OUTPUT GPIO14_OUTPUT_SET
|
||||
|
||||
#define SPI_MISO_READ GPIO12_IN
|
||||
#define SPI_CS_LO GPIO15_L
|
||||
#define SPI_CS_HI GPIO15_H
|
||||
|
||||
#define SPI_FAST
|
||||
#define SPI_CLK_LO GPIO14_L
|
||||
#define SPI_CLK_HI GPIO14_H
|
||||
|
||||
#define SPI_MOSI_LO GPIO13_L
|
||||
#define SPI_MOSI_HI GPIO13_H
|
||||
|
||||
#define SPI_MISO_READ GPIO12_IN
|
||||
|
||||
#define SPI_FAST
|
||||
|
||||
#elif (PLATFORM == NODE32S)
|
||||
|
||||
#define SPI_CS_OUTPUT GPIO15_OUTPUT_SET
|
||||
#define SPI_MOSI_OUTPUT GPIO13_OUTPUT_SET
|
||||
#define SPI_MISO_INPUT GPIO12_INPUT_SET
|
||||
#define SPI_MISO_NO_PULLUP GPIO12_INPUT_PULLUP_UNSET
|
||||
#define SPI_CLK_OUTPUT GPIO14_OUTPUT_SET
|
||||
|
||||
#define SPI_CS_LO GPIO15_L
|
||||
#define SPI_CS_HI GPIO15_H
|
||||
|
||||
#define SPI_CLK_LO GPIO14_L
|
||||
#define SPI_CLK_HI GPIO14_H
|
||||
|
||||
#define SPI_MOSI_LO GPIO13_L
|
||||
#define SPI_MOSI_HI GPIO13_H
|
||||
|
||||
#define SPI_MISO_READ GPIO12_IN
|
||||
|
||||
#define SPI_FAST
|
||||
|
||||
#endif
|
||||
|
||||
namespace spi {
|
||||
|
||||
|
||||
160
net/HTTP.h
Normal file
160
net/HTTP.h
Normal file
@@ -0,0 +1,160 @@
|
||||
#ifndef HTTP_H
|
||||
#define HTTP_H
|
||||
|
||||
#include "TCP.h"
|
||||
#include "../Debug.h"
|
||||
|
||||
class HTTPClient;
|
||||
|
||||
typedef void (*HTTPCBodyDataCallback)(HTTPClient* httpc, const uint8_t* data, uint16_t len);
|
||||
typedef void (*HTTPCConnectCallback)(HTTPClient* httpc);
|
||||
typedef void (*HTTPCDisconnectCallback)(HTTPClient* httpc);
|
||||
|
||||
|
||||
class HTTPClient {
|
||||
|
||||
static constexpr const char* NAME = "HTTPC";
|
||||
TCP tcp;
|
||||
|
||||
espconn dns;
|
||||
ip_addr_t ip;
|
||||
char host[64];
|
||||
char query[128];
|
||||
bool gotHeader = false;
|
||||
int numBreaks = 0;
|
||||
|
||||
HTTPCConnectCallback onConnect = nullptr;
|
||||
HTTPCDisconnectCallback onDisconnect = nullptr;
|
||||
HTTPCBodyDataCallback onBodyData = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
HTTPClient() {
|
||||
debugMod(NAME, "init()");
|
||||
tcp.setUserData(this);
|
||||
tcp.setDataCallback(_onData);
|
||||
tcp.setConnectCallback(_onConnect);
|
||||
tcp.setDisconnectCallback(_onDisconnect);
|
||||
}
|
||||
|
||||
void hold() {
|
||||
tcp.hold();
|
||||
}
|
||||
|
||||
void unhold() {
|
||||
tcp.unhold();
|
||||
}
|
||||
|
||||
void setBodyDataCallback(HTTPCBodyDataCallback c) {
|
||||
this->onBodyData = c;
|
||||
}
|
||||
|
||||
void setConnectCallback(HTTPCConnectCallback c) {
|
||||
this->onConnect = c;
|
||||
}
|
||||
|
||||
void setDisconnectCallback(HTTPCDisconnectCallback c) {
|
||||
this->onDisconnect = c;
|
||||
}
|
||||
|
||||
/** connect to the given IP/Port */
|
||||
void connect(const char* url) {
|
||||
//strcpy(this->url, url);
|
||||
|
||||
const char* hostStart = &url[7]; // skip the "http://"
|
||||
const char* hostEnd = strchr(hostStart, '/'); // find the terminating /
|
||||
strncpy(this->host, hostStart, hostEnd-hostStart); // hostname only
|
||||
this->host[hostEnd-hostStart] = 0; // 0 terminator!!
|
||||
strcpy(this->query, hostEnd); // query only
|
||||
|
||||
debugMod3(NAME, "connect(%s) -> host: '%s' query: '%s'", url, this->host, this->query);
|
||||
|
||||
resolveHost(this->host);
|
||||
|
||||
}
|
||||
|
||||
void disconnect() {
|
||||
tcp.disconnect();
|
||||
gotHeader = false;
|
||||
numBreaks = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** from TCP: connected */
|
||||
static void _onConnect(TCP* tcp) {
|
||||
debugMod(NAME, "connected");
|
||||
HTTPClient* httpc = (HTTPClient*) tcp->getUserData();
|
||||
if (httpc->onConnect) {httpc->onConnect(httpc);}
|
||||
httpc->sendRequest();
|
||||
}
|
||||
|
||||
/** from TCP: disconnected */
|
||||
static void _onDisconnect(TCP* tcp) {
|
||||
debugMod(NAME, "disconnected");
|
||||
HTTPClient* httpc = (HTTPClient*) tcp->getUserData();
|
||||
if (httpc->onDisconnect) {httpc->onDisconnect(httpc);}
|
||||
}
|
||||
|
||||
/** from TCP: got data */
|
||||
static void _onData(TCP* tcp, const uint8_t* data, const uint16_t dataLen) {
|
||||
HTTPClient* httpc = (HTTPClient*) tcp->getUserData();
|
||||
httpc->onData(data, dataLen);
|
||||
}
|
||||
|
||||
/** analyze incoming data */
|
||||
void onData(const uint8_t* data, uint16_t dataLen) {
|
||||
|
||||
// header not yet received. scan incoming data. count number of consecutive linebreaks
|
||||
if (!gotHeader) {
|
||||
while(dataLen && !gotHeader) {
|
||||
const char c = *data;
|
||||
if (c == '\r' || c == '\n') {++numBreaks;} else {numBreaks = 0;}
|
||||
if (numBreaks == 4) {
|
||||
debugMod(NAME, "got header");
|
||||
gotHeader = true;
|
||||
}
|
||||
++data; --dataLen;
|
||||
}
|
||||
}
|
||||
|
||||
// maybe we got the header now
|
||||
if (gotHeader && dataLen) {
|
||||
if (onBodyData) {
|
||||
onBodyData(this, data, dataLen);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** resolve hostname. creates callback */
|
||||
void resolveHost(const char* c) {
|
||||
debugMod1(NAME, "dns lookup: %s", c);
|
||||
dns.reverse = (void*) this;
|
||||
espconn_gethostbyname(&dns, c, &ip, _onHostResolved);
|
||||
}
|
||||
|
||||
/** send the request header */
|
||||
void sendRequest() {
|
||||
char buf[128];
|
||||
const int len = os_sprintf(buf, "GET %s HTTP/1.1\r\nicy-metadata:1\r\n\r\n", this->query);
|
||||
debugMod(NAME, buf);
|
||||
tcp.send((const uint8_t*)buf, len);
|
||||
}
|
||||
|
||||
static void _onHostResolved(const char* name, ip_addr_t* ipaddr, void* arg ) {
|
||||
HTTPClient* http = (HTTPClient*) ((espconn*)arg)->reverse;
|
||||
if (ipaddr) {
|
||||
//debugMod1(NAME, "dns lookup returned: %s", tmp.toString());
|
||||
http->tcp.connect(IP(*ipaddr), 80);
|
||||
} else {
|
||||
debugMod1(NAME, "dns lookup failed: %s", name);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // HTTP_H
|
||||
31
net/IP.h
31
net/IP.h
@@ -5,21 +5,40 @@
|
||||
|
||||
struct IP {
|
||||
|
||||
uint32_t val;
|
||||
//uint32_t val;
|
||||
ip_addr addr;
|
||||
|
||||
/** empty ctor */
|
||||
IP() : val(0) {
|
||||
;
|
||||
explicit IP() {
|
||||
addr.addr = 0;
|
||||
}
|
||||
|
||||
/** ctor with IP-string */
|
||||
IP(const char* ipStr) {
|
||||
explicit IP(const char* ipStr) {
|
||||
set(ipStr);
|
||||
}
|
||||
|
||||
/** set the IP */
|
||||
/** ctor with ip_addr_t */
|
||||
explicit IP(ip_addr addr) : addr(addr) {
|
||||
;
|
||||
}
|
||||
|
||||
/** set the IP by string: x.x.x.x */
|
||||
void set(const char* ipStr) {
|
||||
val = ipaddr_addr(ipStr);
|
||||
addr.addr = ipaddr_addr(ipStr);
|
||||
}
|
||||
|
||||
/** convert to ip_addr/ip_addr_t */
|
||||
const ip_addr* getPtr() const {
|
||||
return &addr;
|
||||
}
|
||||
|
||||
/** convert to string */
|
||||
const char* toString() const {
|
||||
//static char str[16];
|
||||
//ipaddr_aton(str, (ip_addr*)&addr);
|
||||
//return str;
|
||||
return ipaddr_ntoa(&addr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
170
net/TCP.h
Normal file
170
net/TCP.h
Normal file
@@ -0,0 +1,170 @@
|
||||
#ifndef TCP_H
|
||||
#define TCP_H
|
||||
|
||||
extern "C" {
|
||||
#include "mem.h"
|
||||
#include "espconn.h"
|
||||
}
|
||||
|
||||
class TCP;
|
||||
|
||||
typedef void (*TCPDataCallback)(TCP* tcp, const uint8_t* data, uint16_t len);
|
||||
typedef void (*TCPConnectCallback)(TCP* tcp);
|
||||
typedef void (*TCPDisconnectCallback)(TCP* tcp);
|
||||
|
||||
#include "../Debug.h"
|
||||
#include "IP.h"
|
||||
|
||||
class TCP {
|
||||
|
||||
private:
|
||||
|
||||
static constexpr const char* NAME = "TCP";
|
||||
|
||||
espconn* con;
|
||||
esp_tcp tcp;
|
||||
bool connected = false;
|
||||
|
||||
TCPDataCallback onData = nullptr;
|
||||
TCPConnectCallback onConnect = nullptr;
|
||||
TCPDisconnectCallback onDisconnect = nullptr;
|
||||
void* userData = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
TCP() {
|
||||
init();
|
||||
}
|
||||
|
||||
/** dtor */
|
||||
~TCP() {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
|
||||
/** send data to the other side */
|
||||
bool send(const uint8_t* data, const size_t dataLen) {
|
||||
const int res = espconn_sent(con, (unsigned char*)data, dataLen);
|
||||
return (res == 0);
|
||||
}
|
||||
|
||||
/** connect to the given IP and port */
|
||||
void connect(const IP ip, const Port port) {
|
||||
disconnect();
|
||||
debugMod2(NAME, "connect(%s, %d)", ip.toString(), port);
|
||||
con->proto.tcp->remote_port = port;
|
||||
con->proto.tcp->local_port = espconn_port();
|
||||
os_memcpy(con->proto.tcp->remote_ip, ip.getPtr(), 4);
|
||||
espconn_connect(con);
|
||||
connected = true;
|
||||
}
|
||||
|
||||
|
||||
/** terminate connection */
|
||||
void disconnect() {
|
||||
if (!connected) {return;}
|
||||
espconn_disconnect(con);
|
||||
connected = false;
|
||||
}
|
||||
|
||||
void hold() {
|
||||
if (connected) {
|
||||
espconn_recv_hold(con);
|
||||
}
|
||||
}
|
||||
|
||||
void unhold() {
|
||||
if (connected) {
|
||||
espconn_recv_unhold(con);
|
||||
}
|
||||
}
|
||||
|
||||
/** set the callback to call whenever data is received */
|
||||
void setDataCallback(TCPDataCallback callback) {
|
||||
this->onData = callback;
|
||||
}
|
||||
|
||||
/** set the callback to call when connection is established */
|
||||
void setConnectCallback(TCPConnectCallback callback) {
|
||||
this->onConnect = callback;
|
||||
}
|
||||
|
||||
/** set the callback to call when connection is lost */
|
||||
void setDisconnectCallback(TCPDisconnectCallback callback) {
|
||||
this->onDisconnect = callback;
|
||||
}
|
||||
|
||||
/** attach user-data to this object. can bed used within callbacks */
|
||||
void setUserData(void* ptr) {
|
||||
this->userData = ptr;
|
||||
}
|
||||
|
||||
/** get previously attached user data */
|
||||
void* getUserData() const {
|
||||
return this->userData;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** called for incoming data */
|
||||
static void _onData(void* ptr, char* data, unsigned short len) {
|
||||
TCP* tcp = (TCP*) ((espconn*)ptr)->reverse;
|
||||
if (tcp->onData) {tcp->onData(tcp, (const uint8_t*)data, len);}
|
||||
}
|
||||
|
||||
/** called when connection is established */
|
||||
static void _onConnect(void* ptr) {
|
||||
TCP* tcp = (TCP*) ((espconn*)ptr)->reverse;
|
||||
if (tcp->onConnect) {tcp->onConnect(tcp);}
|
||||
tcp->connected = true;
|
||||
}
|
||||
|
||||
/** called when connection is lost */
|
||||
static void _onDisconnect(void* ptr) {
|
||||
TCP* tcp = (TCP*) ((espconn*)ptr)->reverse;
|
||||
if (tcp->onDisconnect) {tcp->onDisconnect(tcp);}
|
||||
tcp->connected = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** initialize the UDP "connection" */
|
||||
void init() {
|
||||
|
||||
debugMod(NAME, "init()");
|
||||
|
||||
// allocate connection-objects
|
||||
con = (espconn*) os_zalloc(sizeof(espconn));
|
||||
ets_memset( con, 0, sizeof( espconn ) );
|
||||
|
||||
// configure
|
||||
con->type = ESPCONN_TCP;
|
||||
con->state = ESPCONN_NONE;
|
||||
|
||||
//con->proto.tcp = (esp_tcp*) os_zalloc(sizeof(esp_tcp));
|
||||
con->proto.tcp = &tcp;
|
||||
|
||||
// attach ourselves for the callback
|
||||
con->reverse = (void*) this; // user-data to refer to this class
|
||||
espconn_regist_recvcb(con, _onData);
|
||||
espconn_regist_connectcb(con, _onConnect);
|
||||
espconn_regist_disconcb(con, _onDisconnect);
|
||||
// espconn_regist_reconcb(con, _onDisconnect);
|
||||
|
||||
}
|
||||
|
||||
/** cleanup everything */
|
||||
void cleanup() {
|
||||
|
||||
debugMod(NAME, "cleanup()");
|
||||
|
||||
espconn_delete(con);
|
||||
//os_free(con->proto.tcp);
|
||||
os_free(con);
|
||||
con = nullptr;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // TCP_H
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
|
||||
// set remote port and IP
|
||||
con->proto.udp->remote_port = port;
|
||||
os_memcpy(con->proto.udp->remote_ip, &(ip.val), 4);
|
||||
os_memcpy(con->proto.udp->remote_ip, ip.getPtr(), 4);
|
||||
|
||||
//os_printf("send %d bytes\r\n", dataLen);
|
||||
//os_printf("IP: %d.%d.%d.%d\n\r", con->proto.udp->remote_ip[0], con->proto.udp->remote_ip[1], con->proto.udp->remote_ip[2], con->proto.udp->remote_ip[3]);
|
||||
|
||||
Reference in New Issue
Block a user