mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-22 21:23:07 +03:00
commit
e12509e4b3
@ -175,6 +175,9 @@ char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** te
|
||||
uint32_t size = 0;
|
||||
|
||||
if(str == NULL) {
|
||||
if(temp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
start = *temp;
|
||||
} else {
|
||||
start = str;
|
||||
@ -184,6 +187,10 @@ char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** te
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(delimiters == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
end = start;
|
||||
|
||||
while(1) {
|
||||
@ -211,7 +218,9 @@ char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** te
|
||||
}
|
||||
|
||||
char* ICACHE_FLASH_ATTR strtok(char * str, const char * delimiters) {
|
||||
return strtok_r(str, delimiters, NULL);
|
||||
static char * ret = NULL;
|
||||
ret = strtok_r(str, delimiters, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int strcasecmp(const char * str1, const char * str2) {
|
||||
|
@ -69,6 +69,5 @@ void setup(void){
|
||||
}
|
||||
|
||||
void loop(void){
|
||||
mdns.update();
|
||||
server.handleClient();
|
||||
}
|
||||
|
@ -308,6 +308,5 @@ void setup(void){
|
||||
}
|
||||
|
||||
void loop(void){
|
||||
//mdns.update();
|
||||
server.handleClient();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#define LWIP_INTERNAL
|
||||
#include <functional>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@ -168,7 +169,6 @@ int WiFiUDP::endPacket()
|
||||
return 0;
|
||||
|
||||
_ctx->send();
|
||||
_ctx->disconnect();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -28,9 +28,13 @@ extern "C" void esp_schedule();
|
||||
|
||||
#define GET_IP_HDR(pb) reinterpret_cast<ip_hdr*>(((uint8_t*)((pb)->payload)) - UDP_HLEN - IP_HLEN);
|
||||
#define GET_UDP_HDR(pb) reinterpret_cast<udp_hdr*>(((uint8_t*)((pb)->payload)) - UDP_HLEN);
|
||||
|
||||
class UdpContext
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::function<void(void)> rxhandler_t;
|
||||
|
||||
UdpContext()
|
||||
: _pcb(0)
|
||||
, _rx_buf(0)
|
||||
@ -40,8 +44,11 @@ public:
|
||||
, _tx_buf_head(0)
|
||||
, _tx_buf_cur(0)
|
||||
, _tx_buf_offset(0)
|
||||
, _multicast_ttl(1)
|
||||
, _dest_port(0)
|
||||
{
|
||||
_pcb = udp_new();
|
||||
_dest_addr.addr = 0;
|
||||
}
|
||||
|
||||
~UdpContext()
|
||||
@ -79,8 +86,9 @@ public:
|
||||
|
||||
bool connect(ip_addr_t addr, uint16_t port)
|
||||
{
|
||||
err_t err = udp_connect(_pcb, &addr, port);
|
||||
return err == ERR_OK;
|
||||
_dest_addr = addr;
|
||||
_dest_port = port;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool listen(ip_addr_t addr, uint16_t port)
|
||||
@ -107,7 +115,13 @@ public:
|
||||
// newer versions of lwip have an additional field (mcast_ttl) for this purpose
|
||||
// and a macro to set it instead of direct field access
|
||||
// udp_set_multicast_ttl(_pcb, ttl);
|
||||
_pcb->ttl = ttl;
|
||||
_multicast_ttl = ttl;
|
||||
}
|
||||
|
||||
// warning: handler is called from tcp stack context
|
||||
// esp_yield and non-reentrant functions which depend on it will fail
|
||||
void onRx(rxhandler_t handler) {
|
||||
_on_rx = handler;
|
||||
}
|
||||
|
||||
size_t getSize() const
|
||||
@ -173,10 +187,10 @@ public:
|
||||
return _rx_buf != 0;
|
||||
}
|
||||
|
||||
char read()
|
||||
int read()
|
||||
{
|
||||
if (!_rx_buf || _rx_buf->len == _rx_buf_offset)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
char c = reinterpret_cast<char*>(_rx_buf->payload)[_rx_buf_offset];
|
||||
_consume(1);
|
||||
@ -190,7 +204,7 @@ public:
|
||||
|
||||
size_t max_size = _rx_buf->len - _rx_buf_offset;
|
||||
size = (size < max_size) ? size : max_size;
|
||||
DEBUGV(":rd %d, %d, %d\r\n", size, _rx_buf->len, _rx_buf_offset);
|
||||
DEBUGV(":urd %d, %d, %d\r\n", size, _rx_buf->len, _rx_buf_offset);
|
||||
|
||||
os_memcpy(dst, reinterpret_cast<char*>(_rx_buf->payload) + _rx_buf_offset, size);
|
||||
_consume(size);
|
||||
@ -257,10 +271,19 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (addr)
|
||||
udp_sendto(_pcb, _tx_buf_head, addr, port);
|
||||
else
|
||||
udp_send(_pcb, _tx_buf_head);
|
||||
if (!addr) {
|
||||
addr = &_dest_addr;
|
||||
port = _dest_port;
|
||||
}
|
||||
|
||||
uint16_t old_ttl = _pcb->ttl;
|
||||
if (ip_addr_ismulticast(addr)) {
|
||||
_pcb->ttl = _multicast_ttl;
|
||||
}
|
||||
|
||||
udp_sendto(_pcb, _tx_buf_head, addr, port);
|
||||
|
||||
_pcb->ttl = old_ttl;
|
||||
|
||||
for (pbuf* p = _tx_buf_head; p; p = p->next)
|
||||
{
|
||||
@ -281,7 +304,7 @@ private:
|
||||
|
||||
void _reserve(size_t size)
|
||||
{
|
||||
const size_t pbuf_unit_size = 1024;
|
||||
const size_t pbuf_unit_size = 512;
|
||||
if (!_tx_buf_head)
|
||||
{
|
||||
_tx_buf_head = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM);
|
||||
@ -317,16 +340,19 @@ private:
|
||||
{
|
||||
// there is some unread data
|
||||
// chain the new pbuf to the existing one
|
||||
DEBUGV(":rch %d, %d\r\n", _rx_buf->tot_len, pb->tot_len);
|
||||
DEBUGV(":urch %d, %d\r\n", _rx_buf->tot_len, pb->tot_len);
|
||||
pbuf_cat(_rx_buf, pb);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUGV(":rn %d\r\n", pb->tot_len);
|
||||
DEBUGV(":urn %d\r\n", pb->tot_len);
|
||||
_first_buf_taken = false;
|
||||
_rx_buf = pb;
|
||||
_rx_buf_offset = 0;
|
||||
}
|
||||
if (_on_rx) {
|
||||
_on_rx();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -341,6 +367,11 @@ private:
|
||||
int _refcnt;
|
||||
udp_pcb* _pcb;
|
||||
|
||||
ip_addr_t _dest_addr;
|
||||
uint16_t _dest_port;
|
||||
|
||||
uint16_t _multicast_ttl;
|
||||
|
||||
bool _first_buf_taken;
|
||||
pbuf* _rx_buf;
|
||||
size_t _rx_buf_offset;
|
||||
@ -348,6 +379,8 @@ private:
|
||||
pbuf* _tx_buf_head;
|
||||
pbuf* _tx_buf_cur;
|
||||
size_t _tx_buf_offset;
|
||||
|
||||
rxhandler_t _on_rx;
|
||||
};
|
||||
|
||||
|
||||
|
@ -42,6 +42,10 @@ License (MIT license):
|
||||
#define TTL_OFFSET 4
|
||||
#define IP_OFFSET 10
|
||||
|
||||
static const IPAddress MDNS_MULTICAST_ADDR(224, 0, 0, 251);
|
||||
static const int MDNS_MULTICAST_TTL = 1;
|
||||
static const int MDNS_PORT = 5353;
|
||||
|
||||
|
||||
MDNSResponder::MDNSResponder()
|
||||
: _expected(NULL)
|
||||
@ -49,6 +53,7 @@ MDNSResponder::MDNSResponder()
|
||||
, _response(NULL)
|
||||
, _responseLen(0)
|
||||
, _index(0)
|
||||
, _conn(0)
|
||||
{ }
|
||||
|
||||
MDNSResponder::~MDNSResponder() {
|
||||
@ -149,21 +154,37 @@ bool MDNSResponder::begin(const char* domain, IPAddress addr, uint32_t ttlSecond
|
||||
records[IP_OFFSET + 0] = (uint8_t) ipAddress;
|
||||
|
||||
// Open the MDNS socket if it isn't already open.
|
||||
if (!_mdnsConn) {
|
||||
if (!_mdnsConn.beginMulticast(addr, IPAddress(224, 0, 0, 251), 5353)) {
|
||||
if (!_conn) {
|
||||
ip_addr_t ifaddr;
|
||||
ifaddr.addr = (uint32_t) addr;
|
||||
ip_addr_t multicast_addr;
|
||||
multicast_addr.addr = (uint32_t) MDNS_MULTICAST_ADDR;
|
||||
|
||||
if (igmp_joingroup(&ifaddr, &multicast_addr)!= ERR_OK) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_conn = new UdpContext;
|
||||
_conn->ref();
|
||||
|
||||
if (!_conn->listen(*IP_ADDR_ANY, MDNS_PORT)) {
|
||||
return false;
|
||||
}
|
||||
_conn->setMulticastInterface(ifaddr);
|
||||
_conn->setMulticastTTL(MDNS_MULTICAST_TTL);
|
||||
_conn->onRx(std::bind(&MDNSResponder::update, this));
|
||||
_conn->connect(multicast_addr, MDNS_PORT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MDNSResponder::update() {
|
||||
if (!_mdnsConn.parsePacket())
|
||||
if (!_conn->next()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Read available data.
|
||||
int n = _mdnsConn.available();
|
||||
int n = _conn->getSize();
|
||||
|
||||
_index = 0;
|
||||
|
||||
@ -172,7 +193,7 @@ void MDNSResponder::update() {
|
||||
#endif
|
||||
// Look for domain name in request and respond with canned response if found.
|
||||
for (int i = 0; i < n; ++i) {
|
||||
uint8_t ch = tolower(_mdnsConn.read());
|
||||
uint8_t ch = tolower(_conn->read());
|
||||
|
||||
#ifdef MDNS_DEBUG
|
||||
String str(ch, 16);
|
||||
@ -191,9 +212,12 @@ void MDNSResponder::update() {
|
||||
Serial.print("responding, i=");
|
||||
Serial.println(i);
|
||||
#endif
|
||||
_mdnsConn.beginPacketMulticast(IPAddress(224, 0, 0, 251), 5353, _localAddr);
|
||||
_mdnsConn.write(_response, _responseLen);
|
||||
_mdnsConn.endPacket();
|
||||
ip_addr_t multicast_addr;
|
||||
multicast_addr.addr = (uint32_t) MDNS_MULTICAST_ADDR;
|
||||
|
||||
_conn->append(reinterpret_cast<const char*>(_response), _responseLen);
|
||||
_conn->send();
|
||||
|
||||
_index = 0;
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,9 @@ License (MIT license):
|
||||
#include "ESP8266WiFi.h"
|
||||
#include "WiFiUdp.h"
|
||||
|
||||
|
||||
class UdpContext;
|
||||
|
||||
class MDNSResponder {
|
||||
public:
|
||||
MDNSResponder();
|
||||
@ -63,7 +66,7 @@ private:
|
||||
uint8_t* _response;
|
||||
int _responseLen;
|
||||
// Socket for MDNS communication
|
||||
WiFiUDP _mdnsConn;
|
||||
UdpContext* _conn;
|
||||
// local IP Address
|
||||
IPAddress _localAddr;
|
||||
};
|
||||
|
@ -68,9 +68,6 @@ void setup(void)
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
// Check for any mDNS queries and send responses
|
||||
mdns.update();
|
||||
|
||||
// Check if a client has connected
|
||||
WiFiClient client = server.available();
|
||||
if (!client) {
|
||||
|
@ -345,8 +345,6 @@ boolean SDClass::begin(uint8_t csPin, uint32_t speed) {
|
||||
root.openRoot(volume);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// this little helper is used to traverse paths
|
||||
SdFile SDClass::getParentDir(const char *filepath, int *index) {
|
||||
// get parent directory
|
||||
|
@ -33,9 +33,13 @@ static void spiSend(uint8_t b) {
|
||||
SPDR = b;
|
||||
while (!(SPSR & (1 << SPIF)))
|
||||
;
|
||||
#else
|
||||
#ifdef ESP8266
|
||||
SPI.write(b);
|
||||
#else
|
||||
SPI.transfer(b);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
/** Receive a byte from the card */
|
||||
static uint8_t spiRec(void) {
|
||||
@ -116,8 +120,14 @@ uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
|
||||
// send command
|
||||
spiSend(cmd | 0x40);
|
||||
|
||||
#ifdef ESP8266
|
||||
// send argument
|
||||
SPI.write32(arg, true);
|
||||
#else
|
||||
// send argument
|
||||
for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s);
|
||||
#endif
|
||||
|
||||
|
||||
// send CRC
|
||||
uint8_t crc = 0xFF;
|
||||
@ -424,7 +434,14 @@ uint8_t Sd2Card::readData(uint32_t block,
|
||||
dst[n] = SPDR;
|
||||
|
||||
#else // OPTIMIZE_HARDWARE_SPI
|
||||
#ifdef ESP8266
|
||||
// skip data before offset
|
||||
SPI.transferBytes(NULL, NULL, offset_);
|
||||
|
||||
// transfer data
|
||||
SPI.transferBytes(NULL, dst, count);
|
||||
|
||||
#else
|
||||
// skip data before offset
|
||||
for (;offset_ < offset; offset_++) {
|
||||
spiRec();
|
||||
@ -433,6 +450,7 @@ uint8_t Sd2Card::readData(uint32_t block,
|
||||
for (uint16_t i = 0; i < count; i++) {
|
||||
dst[i] = spiRec();
|
||||
}
|
||||
#endif
|
||||
#endif // OPTIMIZE_HARDWARE_SPI
|
||||
|
||||
offset_ += count;
|
||||
@ -463,7 +481,11 @@ void Sd2Card::readEnd(void) {
|
||||
while (!(SPSR & (1 << SPIF)))
|
||||
;
|
||||
#else // OPTIMIZE_HARDWARE_SPI
|
||||
#ifdef ESP8266
|
||||
SPI.transferBytes(NULL, NULL, (514-offset_));
|
||||
#else
|
||||
while (offset_++ < 514) spiRec();
|
||||
#endif
|
||||
#endif // OPTIMIZE_HARDWARE_SPI
|
||||
chipSelectHigh();
|
||||
inBlock_ = 0;
|
||||
@ -479,7 +501,11 @@ uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) {
|
||||
}
|
||||
if (!waitStartBlock()) goto fail;
|
||||
// transfer data
|
||||
#ifdef ESP8266
|
||||
SPI.transferBytes(NULL, dst, 16);
|
||||
#else
|
||||
for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec();
|
||||
#endif
|
||||
spiRec(); // get first crc byte
|
||||
spiRec(); // get second crc byte
|
||||
chipSelectHigh();
|
||||
@ -646,13 +672,21 @@ uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) {
|
||||
|
||||
#else // OPTIMIZE_HARDWARE_SPI
|
||||
spiSend(token);
|
||||
#ifdef ESP8266
|
||||
// send argument
|
||||
SPI.writeBytes((uint8_t *)src, 512);
|
||||
#else
|
||||
for (uint16_t i = 0; i < 512; i++) {
|
||||
spiSend(src[i]);
|
||||
}
|
||||
#endif
|
||||
#endif // OPTIMIZE_HARDWARE_SPI
|
||||
#ifdef ESP8266
|
||||
SPI.write16(0xFFFF, true);
|
||||
#else
|
||||
spiSend(0xff); // dummy crc
|
||||
spiSend(0xff); // dummy crc
|
||||
|
||||
#endif
|
||||
status_ = spiRec();
|
||||
if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
|
||||
error(SD_CARD_ERROR_WRITE);
|
||||
|
@ -36,6 +36,7 @@ typedef union {
|
||||
SPIClass SPI;
|
||||
|
||||
SPIClass::SPIClass() {
|
||||
useHwCs = false;
|
||||
}
|
||||
|
||||
void SPIClass::begin() {
|
||||
@ -54,9 +55,26 @@ void SPIClass::end() {
|
||||
pinMode(SCK, INPUT);
|
||||
pinMode(MISO, INPUT);
|
||||
pinMode(MOSI, INPUT);
|
||||
if(useHwCs) {
|
||||
pinMode(SS, INPUT);
|
||||
}
|
||||
}
|
||||
|
||||
void SPIClass::setHwCs(bool use) {
|
||||
if(use) {
|
||||
pinMode(SS, SPECIAL); ///< GPIO15
|
||||
SPI1U |= (SPIUCSSETUP | SPIUCSHOLD);
|
||||
} else {
|
||||
if(useHwCs) {
|
||||
pinMode(SS, INPUT);
|
||||
SPI1U &= ~(SPIUCSSETUP | SPIUCSHOLD);
|
||||
}
|
||||
}
|
||||
useHwCs = use;
|
||||
}
|
||||
|
||||
void SPIClass::beginTransaction(SPISettings settings) {
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
setFrequency(settings._clock);
|
||||
setBitOrder(settings._bitOrder);
|
||||
setDataMode(settings._dataMode);
|
||||
@ -198,13 +216,19 @@ void SPIClass::setClockDivider(uint32_t clockDiv) {
|
||||
SPI1CLK = clockDiv;
|
||||
}
|
||||
|
||||
inline void SPIClass::setDataBits(uint16_t bits) {
|
||||
const uint32_t mask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO));
|
||||
bits--;
|
||||
SPI1U1 = ((SPI1U1 & mask) | ((bits << SPILMOSI) | (bits << SPILMISO)));
|
||||
}
|
||||
|
||||
uint8_t SPIClass::transfer(uint8_t data) {
|
||||
while(SPI1CMD & SPIBUSY)
|
||||
;
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
// reset to 8Bit mode
|
||||
setDataBits(8);
|
||||
SPI1W0 = data;
|
||||
SPI1CMD |= SPIBUSY;
|
||||
while(SPI1CMD & SPIBUSY)
|
||||
;
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
return (uint8_t) (SPI1W0 & 0xff);
|
||||
}
|
||||
|
||||
@ -230,3 +254,177 @@ uint16_t SPIClass::transfer16(uint16_t data) {
|
||||
return out.val;
|
||||
}
|
||||
|
||||
void SPIClass::write(uint8_t data) {
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
// reset to 8Bit mode
|
||||
setDataBits(8);
|
||||
SPI1W0 = data;
|
||||
SPI1CMD |= SPIBUSY;
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
}
|
||||
|
||||
void SPIClass::write16(uint16_t data) {
|
||||
write16(data, !(SPI1C & (SPICWBO | SPICRBO)));
|
||||
}
|
||||
|
||||
void SPIClass::write16(uint16_t data, bool msb) {
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
// Set to 16Bits transfer
|
||||
setDataBits(16);
|
||||
if(msb) {
|
||||
// MSBFIRST Byte first
|
||||
SPI1W0 = (data >> 8) | (data << 8);
|
||||
SPI1CMD |= SPIBUSY;
|
||||
} else {
|
||||
// LSBFIRST Byte first
|
||||
SPI1W0 = data;
|
||||
SPI1CMD |= SPIBUSY;
|
||||
}
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
}
|
||||
|
||||
void SPIClass::write32(uint32_t data) {
|
||||
write32(data, !(SPI1C & (SPICWBO | SPICRBO)));
|
||||
}
|
||||
|
||||
void SPIClass::write32(uint32_t data, bool msb) {
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
// Set to 32Bits transfer
|
||||
setDataBits(32);
|
||||
if(msb) {
|
||||
union {
|
||||
uint32_t l;
|
||||
uint8_t b[4];
|
||||
} data_;
|
||||
data_.l = data;
|
||||
// MSBFIRST Byte first
|
||||
SPI1W0 = (data_.b[3] | (data_.b[2] << 8) | (data_.b[1] << 16) | (data_.b[0] << 24));
|
||||
SPI1CMD |= SPIBUSY;
|
||||
} else {
|
||||
// LSBFIRST Byte first
|
||||
SPI1W0 = data;
|
||||
SPI1CMD |= SPIBUSY;
|
||||
}
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
}
|
||||
|
||||
void SPIClass::writeBytes(uint8_t * data, uint32_t size) {
|
||||
while(size) {
|
||||
if(size > 64) {
|
||||
writeBytes_(data, 64);
|
||||
size -= 64;
|
||||
data += 64;
|
||||
} else {
|
||||
writeBytes_(data, size);
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SPIClass::writeBytes_(uint8_t * data, uint8_t size) {
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
// Set Bits to transfer
|
||||
setDataBits(size * 8);
|
||||
|
||||
volatile uint32_t * fifoPtr = &SPI1W0;
|
||||
uint32_t * dataPtr = (uint32_t*) data;
|
||||
uint8_t dataSize = ((size + 3) / 4);
|
||||
|
||||
while(dataSize--) {
|
||||
*fifoPtr = *dataPtr;
|
||||
dataPtr++;
|
||||
fifoPtr++;
|
||||
}
|
||||
|
||||
SPI1CMD |= SPIBUSY;
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
}
|
||||
|
||||
void SPIClass::writePattern(uint8_t * data, uint8_t size, uint32_t repeat) {
|
||||
if(size > 64) return; //max Hardware FIFO
|
||||
|
||||
uint32_t byte = (size * repeat);
|
||||
uint8_t r = (64 / size);
|
||||
|
||||
while(byte) {
|
||||
if(byte > 64) {
|
||||
writePattern_(data, size, r);
|
||||
byte -= 64;
|
||||
} else {
|
||||
writePattern_(data, size, (byte / size));
|
||||
byte = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SPIClass::writePattern_(uint8_t * data, uint8_t size, uint8_t repeat) {
|
||||
uint8_t bytes = (size * repeat);
|
||||
uint8_t buffer[64];
|
||||
uint8_t * bufferPtr = &buffer[0];
|
||||
uint8_t * dataPtr;
|
||||
uint8_t dataSize = bytes;
|
||||
for(uint8_t i = 0; i < repeat; i++) {
|
||||
dataSize = size;
|
||||
dataPtr = data;
|
||||
while(dataSize--) {
|
||||
*bufferPtr = *dataPtr;
|
||||
dataPtr++;
|
||||
bufferPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
writeBytes(&buffer[0], bytes);
|
||||
}
|
||||
|
||||
void SPIClass::transferBytes(uint8_t * out, uint8_t * in, uint32_t size) {
|
||||
while(size) {
|
||||
if(size > 64) {
|
||||
transferBytes_(out, in, 64);
|
||||
size -= 64;
|
||||
if(out) out += 64;
|
||||
if(in) in += 64;
|
||||
} else {
|
||||
transferBytes_(out, in, size);
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SPIClass::transferBytes_(uint8_t * out, uint8_t * in, uint8_t size) {
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
// Set in/out Bits to transfer
|
||||
|
||||
setDataBits(size * 8);
|
||||
|
||||
volatile uint32_t * fifoPtr = &SPI1W0;
|
||||
uint8_t dataSize = ((size + 3) / 4);
|
||||
|
||||
if(out) {
|
||||
uint32_t * dataPtr = (uint32_t*) out;
|
||||
while(dataSize--) {
|
||||
*fifoPtr = *dataPtr;
|
||||
dataPtr++;
|
||||
fifoPtr++;
|
||||
}
|
||||
} else {
|
||||
// no out data only read fill with dummy data!
|
||||
while(dataSize--) {
|
||||
*fifoPtr = 0xFFFFFFFF;
|
||||
fifoPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
SPI1CMD |= SPIBUSY;
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
|
||||
if(in) {
|
||||
volatile uint8_t * fifoPtr8 = (volatile uint8_t *) &SPI1W0;
|
||||
dataSize = size;
|
||||
while(dataSize--) {
|
||||
*in = *fifoPtr8;
|
||||
in++;
|
||||
fifoPtr8++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,7 @@ public:
|
||||
SPIClass();
|
||||
void begin();
|
||||
void end();
|
||||
void setHwCs(bool use);
|
||||
void setBitOrder(uint8_t bitOrder);
|
||||
void setDataMode(uint8_t dataMode);
|
||||
void setFrequency(uint32_t freq);
|
||||
@ -71,7 +72,21 @@ public:
|
||||
void beginTransaction(SPISettings settings);
|
||||
uint8_t transfer(uint8_t data);
|
||||
uint16_t transfer16(uint16_t data);
|
||||
void write(uint8_t data);
|
||||
void write16(uint16_t data);
|
||||
void write16(uint16_t data, bool msb);
|
||||
void write32(uint32_t data);
|
||||
void write32(uint32_t data, bool msb);
|
||||
void writeBytes(uint8_t * data, uint32_t size);
|
||||
void writePattern(uint8_t * data, uint8_t size, uint32_t repeat);
|
||||
void transferBytes(uint8_t * out, uint8_t * in, uint32_t size);
|
||||
void endTransaction(void);
|
||||
private:
|
||||
bool useHwCs;
|
||||
void writeBytes_(uint8_t * data, uint8_t size);
|
||||
void writePattern_(uint8_t * data, uint8_t size, uint8_t repeat);
|
||||
void transferBytes_(uint8_t * out, uint8_t * in, uint8_t size);
|
||||
inline void setDataBits(uint16_t bits);
|
||||
};
|
||||
|
||||
extern SPIClass SPI;
|
||||
|
@ -23,7 +23,7 @@ compiler.S.flags=-c -g -x assembler-with-cpp -MMD
|
||||
compiler.c.elf.ldscript=eagle.app.v6.ld
|
||||
compiler.c.elf.flags=-nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static "-L{compiler.sdk.path}/lib" "-L{compiler.sdk.path}/ld" "-T{compiler.c.elf.ldscript}"
|
||||
compiler.c.elf.cmd=xtensa-lx106-elf-gcc
|
||||
compiler.c.elf.libs=-lm -lc -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig
|
||||
compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig
|
||||
|
||||
compiler.cpp.cmd=xtensa-lx106-elf-g++
|
||||
compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -std=c++11 -MMD
|
||||
|
Loading…
x
Reference in New Issue
Block a user