1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-16 11:21:18 +03:00

Merge pull request #17 from esp8266/esp8266

pull latest changes
This commit is contained in:
ficeto
2015-05-12 20:53:19 +03:00
16 changed files with 738 additions and 397 deletions

View File

@ -175,6 +175,9 @@ char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** te
uint32_t size = 0; uint32_t size = 0;
if(str == NULL) { if(str == NULL) {
if(temp == NULL) {
return NULL;
}
start = *temp; start = *temp;
} else { } else {
start = str; start = str;
@ -184,6 +187,10 @@ char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** te
return NULL; return NULL;
} }
if(delimiters == NULL) {
return NULL;
}
end = start; end = start;
while(1) { 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) { 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) { int strcasecmp(const char * str1, const char * str2) {

View File

@ -69,6 +69,5 @@ void setup(void){
} }
void loop(void){ void loop(void){
mdns.update();
server.handleClient(); server.handleClient();
} }

View File

@ -308,6 +308,5 @@ void setup(void){
} }
void loop(void){ void loop(void){
//mdns.update();
server.handleClient(); server.handleClient();
} }

View File

@ -21,7 +21,8 @@
*/ */
#define LWIP_INTERNAL #define LWIP_INTERNAL
#include <functional>
extern "C" extern "C"
{ {
#include "include/wl_definitions.h" #include "include/wl_definitions.h"
@ -168,7 +169,6 @@ int WiFiUDP::endPacket()
return 0; return 0;
_ctx->send(); _ctx->send();
_ctx->disconnect();
return 1; return 1;
} }

View File

@ -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_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); #define GET_UDP_HDR(pb) reinterpret_cast<udp_hdr*>(((uint8_t*)((pb)->payload)) - UDP_HLEN);
class UdpContext class UdpContext
{ {
public: public:
typedef std::function<void(void)> rxhandler_t;
UdpContext() UdpContext()
: _pcb(0) : _pcb(0)
, _rx_buf(0) , _rx_buf(0)
@ -40,8 +44,11 @@ public:
, _tx_buf_head(0) , _tx_buf_head(0)
, _tx_buf_cur(0) , _tx_buf_cur(0)
, _tx_buf_offset(0) , _tx_buf_offset(0)
, _multicast_ttl(1)
, _dest_port(0)
{ {
_pcb = udp_new(); _pcb = udp_new();
_dest_addr.addr = 0;
} }
~UdpContext() ~UdpContext()
@ -79,8 +86,9 @@ public:
bool connect(ip_addr_t addr, uint16_t port) bool connect(ip_addr_t addr, uint16_t port)
{ {
err_t err = udp_connect(_pcb, &addr, port); _dest_addr = addr;
return err == ERR_OK; _dest_port = port;
return true;
} }
bool listen(ip_addr_t addr, uint16_t port) 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 // newer versions of lwip have an additional field (mcast_ttl) for this purpose
// and a macro to set it instead of direct field access // and a macro to set it instead of direct field access
// udp_set_multicast_ttl(_pcb, ttl); // 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 size_t getSize() const
@ -173,10 +187,10 @@ public:
return _rx_buf != 0; return _rx_buf != 0;
} }
char read() int read()
{ {
if (!_rx_buf || _rx_buf->len == _rx_buf_offset) if (!_rx_buf || _rx_buf->len == _rx_buf_offset)
return 0; return -1;
char c = reinterpret_cast<char*>(_rx_buf->payload)[_rx_buf_offset]; char c = reinterpret_cast<char*>(_rx_buf->payload)[_rx_buf_offset];
_consume(1); _consume(1);
@ -190,7 +204,7 @@ public:
size_t max_size = _rx_buf->len - _rx_buf_offset; size_t max_size = _rx_buf->len - _rx_buf_offset;
size = (size < max_size) ? size : max_size; 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); os_memcpy(dst, reinterpret_cast<char*>(_rx_buf->payload) + _rx_buf_offset, size);
_consume(size); _consume(size);
@ -257,10 +271,19 @@ public:
} }
} }
if (addr) if (!addr) {
udp_sendto(_pcb, _tx_buf_head, addr, port); addr = &_dest_addr;
else port = _dest_port;
udp_send(_pcb, _tx_buf_head); }
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) for (pbuf* p = _tx_buf_head; p; p = p->next)
{ {
@ -281,7 +304,7 @@ private:
void _reserve(size_t size) void _reserve(size_t size)
{ {
const size_t pbuf_unit_size = 1024; const size_t pbuf_unit_size = 512;
if (!_tx_buf_head) if (!_tx_buf_head)
{ {
_tx_buf_head = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM); _tx_buf_head = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM);
@ -317,16 +340,19 @@ private:
{ {
// there is some unread data // there is some unread data
// chain the new pbuf to the existing one // 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); pbuf_cat(_rx_buf, pb);
} }
else else
{ {
DEBUGV(":rn %d\r\n", pb->tot_len); DEBUGV(":urn %d\r\n", pb->tot_len);
_first_buf_taken = false; _first_buf_taken = false;
_rx_buf = pb; _rx_buf = pb;
_rx_buf_offset = 0; _rx_buf_offset = 0;
} }
if (_on_rx) {
_on_rx();
}
} }
@ -341,6 +367,11 @@ private:
int _refcnt; int _refcnt;
udp_pcb* _pcb; udp_pcb* _pcb;
ip_addr_t _dest_addr;
uint16_t _dest_port;
uint16_t _multicast_ttl;
bool _first_buf_taken; bool _first_buf_taken;
pbuf* _rx_buf; pbuf* _rx_buf;
size_t _rx_buf_offset; size_t _rx_buf_offset;
@ -348,6 +379,8 @@ private:
pbuf* _tx_buf_head; pbuf* _tx_buf_head;
pbuf* _tx_buf_cur; pbuf* _tx_buf_cur;
size_t _tx_buf_offset; size_t _tx_buf_offset;
rxhandler_t _on_rx;
}; };

View File

@ -42,6 +42,10 @@ License (MIT license):
#define TTL_OFFSET 4 #define TTL_OFFSET 4
#define IP_OFFSET 10 #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() MDNSResponder::MDNSResponder()
: _expected(NULL) : _expected(NULL)
@ -49,6 +53,7 @@ MDNSResponder::MDNSResponder()
, _response(NULL) , _response(NULL)
, _responseLen(0) , _responseLen(0)
, _index(0) , _index(0)
, _conn(0)
{ } { }
MDNSResponder::~MDNSResponder() { MDNSResponder::~MDNSResponder() {
@ -149,21 +154,37 @@ bool MDNSResponder::begin(const char* domain, IPAddress addr, uint32_t ttlSecond
records[IP_OFFSET + 0] = (uint8_t) ipAddress; records[IP_OFFSET + 0] = (uint8_t) ipAddress;
// Open the MDNS socket if it isn't already open. // Open the MDNS socket if it isn't already open.
if (!_mdnsConn) { if (!_conn) {
if (!_mdnsConn.beginMulticast(addr, IPAddress(224, 0, 0, 251), 5353)) { 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; 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; return true;
} }
void MDNSResponder::update() { void MDNSResponder::update() {
if (!_mdnsConn.parsePacket()) if (!_conn->next()) {
return; return;
}
// Read available data. // Read available data.
int n = _mdnsConn.available(); int n = _conn->getSize();
_index = 0; _index = 0;
@ -172,7 +193,7 @@ void MDNSResponder::update() {
#endif #endif
// Look for domain name in request and respond with canned response if found. // Look for domain name in request and respond with canned response if found.
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
uint8_t ch = tolower(_mdnsConn.read()); uint8_t ch = tolower(_conn->read());
#ifdef MDNS_DEBUG #ifdef MDNS_DEBUG
String str(ch, 16); String str(ch, 16);
@ -191,9 +212,12 @@ void MDNSResponder::update() {
Serial.print("responding, i="); Serial.print("responding, i=");
Serial.println(i); Serial.println(i);
#endif #endif
_mdnsConn.beginPacketMulticast(IPAddress(224, 0, 0, 251), 5353, _localAddr); ip_addr_t multicast_addr;
_mdnsConn.write(_response, _responseLen); multicast_addr.addr = (uint32_t) MDNS_MULTICAST_ADDR;
_mdnsConn.endPacket();
_conn->append(reinterpret_cast<const char*>(_response), _responseLen);
_conn->send();
_index = 0; _index = 0;
} }
} }

View File

@ -46,6 +46,9 @@ License (MIT license):
#include "ESP8266WiFi.h" #include "ESP8266WiFi.h"
#include "WiFiUdp.h" #include "WiFiUdp.h"
class UdpContext;
class MDNSResponder { class MDNSResponder {
public: public:
MDNSResponder(); MDNSResponder();
@ -63,7 +66,7 @@ private:
uint8_t* _response; uint8_t* _response;
int _responseLen; int _responseLen;
// Socket for MDNS communication // Socket for MDNS communication
WiFiUDP _mdnsConn; UdpContext* _conn;
// local IP Address // local IP Address
IPAddress _localAddr; IPAddress _localAddr;
}; };

View File

@ -68,9 +68,6 @@ void setup(void)
void loop(void) void loop(void)
{ {
// Check for any mDNS queries and send responses
mdns.update();
// Check if a client has connected // Check if a client has connected
WiFiClient client = server.available(); WiFiClient client = server.available();
if (!client) { if (!client) {

View File

@ -36,6 +36,7 @@ typedef union {
SPIClass SPI; SPIClass SPI;
SPIClass::SPIClass() { SPIClass::SPIClass() {
useHwCs = false;
} }
void SPIClass::begin() { void SPIClass::begin() {
@ -54,9 +55,26 @@ void SPIClass::end() {
pinMode(SCK, INPUT); pinMode(SCK, INPUT);
pinMode(MISO, INPUT); pinMode(MISO, INPUT);
pinMode(MOSI, 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) { void SPIClass::beginTransaction(SPISettings settings) {
while(SPI1CMD & SPIBUSY) {}
setFrequency(settings._clock); setFrequency(settings._clock);
setBitOrder(settings._bitOrder); setBitOrder(settings._bitOrder);
setDataMode(settings._dataMode); setDataMode(settings._dataMode);
@ -198,13 +216,19 @@ void SPIClass::setClockDivider(uint32_t clockDiv) {
SPI1CLK = 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) { uint8_t SPIClass::transfer(uint8_t data) {
while(SPI1CMD & SPIBUSY) while(SPI1CMD & SPIBUSY) {}
; // reset to 8Bit mode
setDataBits(8);
SPI1W0 = data; SPI1W0 = data;
SPI1CMD |= SPIBUSY; SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) while(SPI1CMD & SPIBUSY) {}
;
return (uint8_t) (SPI1W0 & 0xff); return (uint8_t) (SPI1W0 & 0xff);
} }
@ -230,3 +254,177 @@ uint16_t SPIClass::transfer16(uint16_t data) {
return out.val; 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++;
}
}
}

View File

@ -64,6 +64,7 @@ public:
SPIClass(); SPIClass();
void begin(); void begin();
void end(); void end();
void setHwCs(bool use);
void setBitOrder(uint8_t bitOrder); void setBitOrder(uint8_t bitOrder);
void setDataMode(uint8_t dataMode); void setDataMode(uint8_t dataMode);
void setFrequency(uint32_t freq); void setFrequency(uint32_t freq);
@ -71,7 +72,21 @@ public:
void beginTransaction(SPISettings settings); void beginTransaction(SPISettings settings);
uint8_t transfer(uint8_t data); uint8_t transfer(uint8_t data);
uint16_t transfer16(uint16_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); 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; extern SPIClass SPI;

View File

@ -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.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.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.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.cmd=xtensa-lx106-elf-g++
compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -std=c++11 -MMD compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -std=c++11 -MMD

View File

@ -11,6 +11,8 @@
Written by Limor Fried/Ladyada for Adafruit Industries. Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution MIT license, all text above must be included in any redistribution
Modified 09 May 2015 by Markus Sattler - rewrite the code add ESP8266 support and many optimizations now 220% fastet (320% total)
****************************************************/ ****************************************************/
#include "Adafruit_ILI9341.h" #include "Adafruit_ILI9341.h"
@ -24,6 +26,16 @@
#include "wiring_private.h" #include "wiring_private.h"
#include <SPI.h> #include <SPI.h>
#ifdef ESP8266
#define hwSPI true
#endif
#define writeCmdDataTmp(cmd, ...) { \
const uint8_t tmp##cmd##_[] = { __VA_ARGS__ }; \
writeCmdData(cmd, (uint8_t *) &tmp##cmd##_[0], sizeof(tmp##cmd##_)); \
}
#ifndef ESP8266 #ifndef ESP8266
// Constructor when using software SPI. All output pins are configurable. // Constructor when using software SPI. All output pins are configurable.
Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t mosi, Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t mosi,
@ -40,15 +52,40 @@ Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t mosi,
// Constructor when using hardware SPI. Faster, but must use SPI pins // Constructor when using hardware SPI. Faster, but must use SPI pins
// specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.) // specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.)
Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t rst) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) { #if defined(ILI9341_USE_HW_CS) || defined(ILI9341_USE_NO_CS)
_cs = cs; Adafruit_ILI9341::Adafruit_ILI9341(int8_t dc, int8_t rst) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) {
_dc = dc; _dc = dc;
_rst = rst; _rst = rst;
hwSPI = true; hwSPI = true;
#ifndef ESP8266 #ifdef ESP8266
_dcMask = digitalPinToBitMask(_dc);
_rstMask = digitalPinToBitMask(_rst);
#else
_mosi = _sclk = 0; _mosi = _sclk = 0;
#endif #endif
} }
#else
Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t rst) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) {
_cs = cs;
_dc = dc;
_rst = rst;
#ifdef ESP8266
_csMask = digitalPinToBitMask(_cs);
_dcMask = digitalPinToBitMask(_dc);
_rstMask = digitalPinToBitMask(_rst);
#else
hwSPI = true;
_mosi = _sclk = 0;
#endif
}
#endif
#ifdef ESP8266
void Adafruit_ILI9341::spiwrite16(uint16_t c) {
SPI.write16(c, true);
}
#endif
void Adafruit_ILI9341::spiwrite(uint8_t c) { void Adafruit_ILI9341::spiwrite(uint8_t c) {
@ -63,7 +100,7 @@ void Adafruit_ILI9341::spiwrite(uint8_t c) {
while(!(SPSR & _BV(SPIF))); while(!(SPSR & _BV(SPIF)));
SPCR = backupSPCR; SPCR = backupSPCR;
#elif defined(TEENSYDUINO) || defined(ESP8266) #elif defined(TEENSYDUINO) || defined(ESP8266)
SPI.transfer(c); SPI.write(c);
#elif defined (__arm__) #elif defined (__arm__)
SPI.setClockDivider(11); // 8-ish MHz (full! speed!) SPI.setClockDivider(11); // 8-ish MHz (full! speed!)
SPI.setBitOrder(MSBFIRST); SPI.setBitOrder(MSBFIRST);
@ -90,73 +127,143 @@ void Adafruit_ILI9341::spiwrite(uint8_t c) {
#endif #endif
} }
void Adafruit_ILI9341::spiwriteBytes(uint8_t * data, uint8_t size) {
#ifdef ESP8266
SPI.writeBytes(data, size);
#else
while(size--) {
spiwrite(*data);
data++;
}
#endif
}
void Adafruit_ILI9341::writecommand(uint8_t c) { void Adafruit_ILI9341::spiwritePattern(uint8_t * data, uint8_t size, uint32_t repeat) {
#ifdef USE_DIGITAL_WRITE #ifdef ESP8266
digitalWrite(_dc, LOW); SPI.writePattern(data, size, repeat);
#else
uint8_t * ptr;
uint8_t i;
while(repeat--) {
ptr = data;
i = size;
while(i--) {
spiwrite(*ptr);
ptr++;
}
}
#endif
}
inline void Adafruit_ILI9341::spiCsLow(void) {
#ifdef ILI9341_USE_DIGITAL_WRITE
digitalWrite(_cs, LOW); digitalWrite(_cs, LOW);
#else #else
#ifdef ESP8266 #ifdef ESP8266
GPOC = digitalPinToBitMask(_dc); #if !defined(ILI9341_USE_HW_CS) && !defined(ILI9341_USE_NO_CS)
GPOC = digitalPinToBitMask(_cs); GPOC = _csMask;
#else
*dcport &= ~dcpinmask;
//*clkport &= ~clkpinmask; // clkport is a NULL pointer when hwSPI==true
//digitalWrite(_sclk, LOW);
*csport &= ~cspinmask;
#endif #endif
#endif
spiwrite(c);
#ifdef USE_DIGITAL_WRITE
digitalWrite(_cs, HIGH);
#else #else
#ifdef ESP8266 *csport &= ~cspinmask;
GPOS = digitalPinToBitMask(_cs);
#else
*csport |= cspinmask;
#endif #endif
#endif #endif
} }
void Adafruit_ILI9341::writedata(uint8_t c) { inline void Adafruit_ILI9341::spiCsHigh(void) {
#ifdef USE_DIGITAL_WRITE #ifdef ILI9341_USE_DIGITAL_WRITE
digitalWrite(_dc, HIGH);
digitalWrite(_cs, LOW);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_dc);
GPOC = digitalPinToBitMask(_cs);
#else
*dcport |= dcpinmask;
//*clkport &= ~clkpinmask; // clkport is a NULL pointer when hwSPI==true
//digitalWrite(_sclk, LOW);
*csport &= ~cspinmask;
#endif
#endif
spiwrite(c);
#ifdef USE_DIGITAL_WRITE
digitalWrite(_cs, HIGH); digitalWrite(_cs, HIGH);
#else #else
#ifdef ESP8266 #ifdef ESP8266
GPOS = digitalPinToBitMask(_cs); #if !defined(ILI9341_USE_HW_CS) && !defined(ILI9341_USE_NO_CS)
GPOS = _csMask;
#endif
#else #else
*csport |= cspinmask; *csport |= cspinmask;
#endif #endif
#endif #endif
}
inline void Adafruit_ILI9341::spiDcLow(void){
#ifdef ILI9341_USE_DIGITAL_WRITE
digitalWrite(_dc, LOW);
#else
#ifdef ESP8266
#ifndef USE_HW_CS
GPOC = _dcMask;
#endif
#else
*dcport &= ~dcpinmask;
#endif
#endif
}
inline void Adafruit_ILI9341::spiDcHigh(void) {
#ifdef ILI9341_USE_DIGITAL_WRITE
digitalWrite(_dc, HIGH);
#else
#ifdef ESP8266
GPOS = _dcMask;
#else
*dcport |= dcpinmask;
#endif
#endif
}
void Adafruit_ILI9341::writecommand(uint8_t c) {
spiDcLow();
spiCsLow();
spiwrite(c);
spiCsHigh();
}
void Adafruit_ILI9341::writedata(uint8_t c) {
spiDcHigh();
spiCsLow();
spiwrite(c);
spiCsHigh();
} }
void Adafruit_ILI9341::writedata(uint8_t * data, uint8_t size) {
spiDcHigh();
spiCsLow();
spiwriteBytes(data, size);
spiCsHigh();
}
void Adafruit_ILI9341::writeCmdData(uint8_t cmd, uint8_t * data, uint8_t size) {
spiDcLow();
spiCsLow();
spiwrite(cmd);
spiDcHigh();
spiwriteBytes(data, size);
spiCsHigh();
}
// If the SPI library has transaction support, these functions // If the SPI library has transaction support, these functions
// establish settings and protect from interference from other // establish settings and protect from interference from other
// libraries. Otherwise, they simply do nothing. // libraries. Otherwise, they simply do nothing.
#ifdef SPI_HAS_TRANSACTION #ifdef SPI_HAS_TRANSACTION
#ifdef ESP8266
SPISettings spiSettings = SPISettings(F_CPU, MSBFIRST, SPI_MODE0);
#else
SPISettings spiSettings = SPISettings(8000000, MSBFIRST, SPI_MODE0);
#endif
static inline void spi_begin(void) __attribute__((always_inline)); static inline void spi_begin(void) __attribute__((always_inline));
static inline void spi_begin(void) { static inline void spi_begin(void) {
#ifdef ESP8266 SPI.beginTransaction(spiSettings);
SPI.beginTransaction(SPISettings(80000000, MSBFIRST, SPI_MODE0));
#else
SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
#endif
} }
static inline void spi_end(void) __attribute__((always_inline)); static inline void spi_end(void) __attribute__((always_inline));
static inline void spi_end(void) { static inline void spi_end(void) {
@ -202,15 +309,17 @@ void Adafruit_ILI9341::commandList(uint8_t *addr) {
void Adafruit_ILI9341::begin(void) { void Adafruit_ILI9341::begin(void) {
if (_rst > 0) { if (_rst > NOT_A_PIN) {
pinMode(_rst, OUTPUT); pinMode(_rst, OUTPUT);
digitalWrite(_rst, LOW); digitalWrite(_rst, LOW);
} }
pinMode(_dc, OUTPUT); pinMode(_dc, OUTPUT);
#ifndef USE_HW_CS
pinMode(_cs, OUTPUT); pinMode(_cs, OUTPUT);
#endif
#ifndef ESP8266 #ifndef ESP8266
#ifndef USE_DIGITAL_WRITE #ifndef ILI9341_USE_DIGITAL_WRITE
csport = portOutputRegister(digitalPinToPort(_cs)); csport = portOutputRegister(digitalPinToPort(_cs));
cspinmask = digitalPinToBitMask(_cs); cspinmask = digitalPinToBitMask(_cs);
dcport = portOutputRegister(digitalPinToPort(_dc)); dcport = portOutputRegister(digitalPinToPort(_dc));
@ -236,6 +345,9 @@ void Adafruit_ILI9341::begin(void) {
SPI.setDataMode(SPI_MODE0); SPI.setDataMode(SPI_MODE0);
#elif defined (ESP8266) #elif defined (ESP8266)
SPI.begin(); SPI.begin();
#ifdef USE_HW_CS
SPI.setHwCs(true);
#endif
#endif #endif
#ifndef ESP8266 #ifndef ESP8266
} else { } else {
@ -251,7 +363,7 @@ void Adafruit_ILI9341::begin(void) {
} }
#endif #endif
// toggle RST low to reset // toggle RST low to reset
if (_rst > 0) { if (_rst > NOT_A_PIN) {
digitalWrite(_rst, HIGH); digitalWrite(_rst, HIGH);
delay(5); delay(5);
digitalWrite(_rst, LOW); digitalWrite(_rst, LOW);
@ -275,108 +387,47 @@ void Adafruit_ILI9341::begin(void) {
//if(cmdList) commandList(cmdList); //if(cmdList) commandList(cmdList);
if (hwSPI) spi_begin(); if (hwSPI) spi_begin();
writecommand(0xEF);
writedata(0x03);
writedata(0x80);
writedata(0x02);
writecommand(0xCF); writeCmdDataTmp(0xEF, 0x03, 0x80, 0x02);
writedata(0x00); writeCmdDataTmp(0xCF, 0x00, 0XC1, 0X30);
writedata(0XC1); writeCmdDataTmp(0xED, 0x64, 0x03, 0X12, 0X81);
writedata(0X30); writeCmdDataTmp(0xE8, 0x85, 0x00, 0x78);
writeCmdDataTmp(0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02);
writeCmdDataTmp(0xF7, 0x20);
writeCmdDataTmp(0xEA, 0x00, 0x00);
writecommand(0xED); //Powercontrol
writedata(0x64); //VRH[5:0]
writedata(0x03); writeCmdDataTmp(ILI9341_PWCTR1, 0x23);
writedata(0X12);
writedata(0X81);
writecommand(0xE8);
writedata(0x85);
writedata(0x00);
writedata(0x78);
writecommand(0xCB); //Powercontrol
writedata(0x39); //SAP[2:0];BT[3:0]
writedata(0x2C); writeCmdDataTmp(ILI9341_PWCTR2, 0x10);
writedata(0x00);
writedata(0x34);
writedata(0x02);
writecommand(0xF7);
writedata(0x20);
writecommand(0xEA); //VCMcontrol
writedata(0x00); writeCmdDataTmp(ILI9341_VMCTR1, 0x3e, 0x28);
writedata(0x00);
//VCMcontrol2
writecommand(ILI9341_PWCTR1); //Power control writeCmdDataTmp(ILI9341_VMCTR2, 0x86);
writedata(0x23); //VRH[5:0]
//MemoryAccessControl
writecommand(ILI9341_PWCTR2); //Power control writeCmdDataTmp(ILI9341_MADCTL, 0x48);
writedata(0x10); //SAP[2:0];BT[3:0]
writeCmdDataTmp(ILI9341_PIXFMT, 0x55);
writecommand(ILI9341_VMCTR1); //VCM control writeCmdDataTmp(ILI9341_FRMCTR1, 0x00, 0x18);
writedata(0x3e); //<2F>Աȶȵ<C8B6><C8B5><EFBFBD>
writedata(0x28); //DisplayFunctionControl
writeCmdDataTmp(ILI9341_DFUNCTR, 0x08, 0x82, 0x27);
//3GammaFunctionDisable
writeCmdDataTmp(0xF2, 0x00);
writecommand(ILI9341_VMCTR2); //VCM control2 //Gammacurveselected
writedata(0x86); //-- writeCmdDataTmp(ILI9341_GAMMASET, 0x01);
writecommand(ILI9341_MADCTL); // Memory Access Control
writedata(0x48);
writecommand(ILI9341_PIXFMT);
writedata(0x55);
writecommand(ILI9341_FRMCTR1); //SetGamma
writedata(0x00); writeCmdDataTmp(ILI9341_GMCTRP1, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00);
writedata(0x18); writeCmdDataTmp(ILI9341_GMCTRN1, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F);
writecommand(ILI9341_DFUNCTR); // Display Function Control
writedata(0x08);
writedata(0x82);
writedata(0x27);
writecommand(0xF2); // 3Gamma Function Disable
writedata(0x00);
writecommand(ILI9341_GAMMASET); //Gamma curve selected
writedata(0x01);
writecommand(ILI9341_GMCTRP1); //Set Gamma
writedata(0x0F);
writedata(0x31);
writedata(0x2B);
writedata(0x0C);
writedata(0x0E);
writedata(0x08);
writedata(0x4E);
writedata(0xF1);
writedata(0x37);
writedata(0x07);
writedata(0x10);
writedata(0x03);
writedata(0x0E);
writedata(0x09);
writedata(0x00);
writecommand(ILI9341_GMCTRN1); //Set Gamma
writedata(0x00);
writedata(0x0E);
writedata(0x14);
writedata(0x03);
writedata(0x11);
writedata(0x07);
writedata(0x31);
writedata(0xC1);
writedata(0x48);
writedata(0x08);
writedata(0x0F);
writedata(0x0C);
writedata(0x31);
writedata(0x36);
writedata(0x0F);
writecommand(ILI9341_SLPOUT); //Exit Sleep writecommand(ILI9341_SLPOUT); //Exit Sleep
if (hwSPI) spi_end(); if (hwSPI) spi_end();
@ -387,217 +438,161 @@ void Adafruit_ILI9341::begin(void) {
} }
void Adafruit_ILI9341::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
spiCsLow();
setAddrWindow_(x0, y0, x1, y1);
spiCsHigh();
}
void Adafruit_ILI9341::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, void Adafruit_ILI9341::setAddrWindow_(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
uint16_t y1) {
writecommand(ILI9341_CASET); // Column addr set uint8_t buffC[] = { (uint8_t) (x0 >> 8), (uint8_t) x0, (uint8_t) (x1 >> 8), (uint8_t) x1 };
writedata(x0 >> 8); uint8_t buffP[] = { (uint8_t) (y0 >> 8), (uint8_t) y0, (uint8_t) (y1 >> 8), (uint8_t) y1 };
writedata(x0 & 0xFF); // XSTART
writedata(x1 >> 8);
writedata(x1 & 0xFF); // XEND
writecommand(ILI9341_PASET); // Row addr set spiDcLow();
writedata(y0>>8); spiwrite(ILI9341_CASET);
writedata(y0); // YSTART spiDcHigh();
writedata(y1>>8); spiwriteBytes(&buffC[0], sizeof(buffC));
writedata(y1); // YEND
spiDcLow();
spiwrite(ILI9341_PASET);
spiDcHigh();
spiwriteBytes(&buffP[0], sizeof(buffP));
spiDcLow();
spiwrite(ILI9341_RAMWR);
spiDcHigh();
writecommand(ILI9341_RAMWR); // write to RAM
} }
void Adafruit_ILI9341::pushColor(uint16_t color) { void Adafruit_ILI9341::pushColor(uint16_t color) {
if (hwSPI) spi_begin(); if (hwSPI) spi_begin();
#ifdef USE_DIGITAL_WRITE
digitalWrite(_dc, HIGH); spiDcHigh();
digitalWrite(_cs, LOW); spiCsLow();
#else
#ifdef ESP8266 #ifdef ESP8266
GPOS = digitalPinToBitMask(_dc); spiwrite16(color);
GPOC = digitalPinToBitMask(_cs);
#else #else
*dcport |= dcpinmask;
*csport &= ~cspinmask;
#endif
#endif
spiwrite(color >> 8); spiwrite(color >> 8);
spiwrite(color); spiwrite(color);
#ifdef USE_DIGITAL_WRITE
digitalWrite(_cs, HIGH);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_cs);
#else
*csport |= cspinmask;
#endif
#endif #endif
spiCsHigh();
if (hwSPI) spi_end(); if (hwSPI) spi_end();
} }
void Adafruit_ILI9341::drawPixel(int16_t x, int16_t y, uint16_t color) { void Adafruit_ILI9341::drawPixel(int16_t x, int16_t y, uint16_t color) {
if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; if((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) {
return;
}
if(hwSPI) {
spi_begin();
}
spiCsLow();
setAddrWindow_(x, y, x + 1, y + 1);
if (hwSPI) spi_begin();
setAddrWindow(x,y,x+1,y+1);
#ifdef USE_DIGITAL_WRITE
digitalWrite(_dc, HIGH);
digitalWrite(_cs, LOW);
#else
#ifdef ESP8266 #ifdef ESP8266
GPOS = digitalPinToBitMask(_dc); spiwrite16(color);
GPOC = digitalPinToBitMask(_cs);
#else #else
*dcport |= dcpinmask; spiwrite(color >> 8);
*csport &= ~cspinmask; spiwrite(color);
#endif
#endif #endif
spiwrite(color >> 8); spiCsHigh();
spiwrite(color);
#ifdef USE_DIGITAL_WRITE if(hwSPI) {
digitalWrite(_cs, HIGH); spi_end();
#else }
#ifdef ESP8266
GPOS = digitalPinToBitMask(_cs);
#else
*csport |= cspinmask;
#endif
#endif
if (hwSPI) spi_end();
} }
void Adafruit_ILI9341::drawFastVLine(int16_t x, int16_t y, int16_t h, void Adafruit_ILI9341::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
uint16_t color) {
// Rudimentary clipping // Rudimentary clipping
if((x >= _width) || (y >= _height)) return; if((x >= _width) || (y >= _height)) return;
if((y + h - 1) >= _height) h = _height - y;
if((y+h-1) >= _height) if(hwSPI) {
h = _height-y; spi_begin();
}
if (hwSPI) spi_begin(); spiCsLow();
setAddrWindow(x, y, x, y+h-1);
uint8_t hi = color >> 8, lo = color; setAddrWindow_(x, y, x, (y + h - 1));
#ifdef USE_DIGITAL_WRITE uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color };
digitalWrite(_dc, HIGH); spiwritePattern(&colorBin[0], 2, h);
digitalWrite(_cs, LOW);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_dc);
GPOC = digitalPinToBitMask(_cs);
#else
*dcport |= dcpinmask;
*csport &= ~cspinmask;
#endif
#endif
while (h--) { spiCsHigh();
spiwrite(hi);
spiwrite(lo); if(hwSPI) {
} spi_end();
#ifdef USE_DIGITAL_WRITE }
digitalWrite(_cs, HIGH);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_cs);
#else
*csport |= cspinmask;
#endif
#endif
if (hwSPI) spi_end();
} }
void Adafruit_ILI9341::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
void Adafruit_ILI9341::drawFastHLine(int16_t x, int16_t y, int16_t w, // Rudimentary clipping
uint16_t color) { if((x >= _width) || (y >= _height)) return;
if((x+w-1) >= _width) w = _width-x;
// Rudimentary clipping if(hwSPI) {
if((x >= _width) || (y >= _height)) return; spi_begin();
if((x+w-1) >= _width) w = _width-x; }
if (hwSPI) spi_begin();
setAddrWindow(x, y, x+w-1, y);
uint8_t hi = color >> 8, lo = color; spiDcHigh();
#ifdef USE_DIGITAL_WRITE spiCsLow();
digitalWrite(_dc, HIGH);
digitalWrite(_cs, LOW); setAddrWindow_(x, y, (x + w - 1), y);
#else
#ifdef ESP8266 uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color };
GPOS = digitalPinToBitMask(_dc); spiwritePattern(&colorBin[0], 2, w);
GPOC = digitalPinToBitMask(_cs);
#else spiCsHigh();
*dcport |= dcpinmask;
*csport &= ~cspinmask; if(hwSPI) {
#endif spi_end();
#endif }
while (w--) {
spiwrite(hi);
spiwrite(lo);
}
#ifdef USE_DIGITAL_WRITE
digitalWrite(_cs, HIGH);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_cs);
#else
*csport |= cspinmask;
#endif
#endif
if (hwSPI) spi_end();
} }
void Adafruit_ILI9341::fillScreen(uint16_t color) { void Adafruit_ILI9341::fillScreen(uint16_t color) {
fillRect(0, 0, _width, _height, color); fillRect(0, 0, _width, _height, color);
} }
// fill a rectangle // fill a rectangle
void Adafruit_ILI9341::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, void Adafruit_ILI9341::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
uint16_t color) {
// rudimentary clipping (drawChar w/big text requires this) // rudimentary clipping (drawChar w/big text requires this)
if((x >= _width) || (y >= _height)) return; if((x >= _width) || (y >= _height))
if((x + w - 1) >= _width) w = _width - x; return;
if((y + h - 1) >= _height) h = _height - y; if((x + w - 1) >= _width)
w = _width - x;
if((y + h - 1) >= _height)
h = _height - y;
if (hwSPI) spi_begin(); if(hwSPI) {
setAddrWindow(x, y, x+w-1, y+h-1); spi_begin();
}
uint8_t hi = color >> 8, lo = color;
spiCsLow();
#ifdef USE_DIGITAL_WRITE
digitalWrite(_dc, HIGH); setAddrWindow_(x, y, x + w - 1, y + h - 1);
digitalWrite(_cs, LOW);
#else uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color };
#ifdef ESP8266 spiwritePattern(&colorBin[0], 2, (w * h));
GPOS = digitalPinToBitMask(_dc);
GPOC = digitalPinToBitMask(_cs); spiCsHigh();
#else
*dcport |= dcpinmask; if(hwSPI) {
*csport &= ~cspinmask; spi_end();
#endif
#endif
for(y=h; y>0; y--) {
for(x=w; x>0; x--) {
spiwrite(hi);
spiwrite(lo);
} }
}
#ifdef USE_DIGITAL_WRITE
digitalWrite(_cs, HIGH);
#else
#ifdef ESP8266
GPOS = digitalPinToBitMask(_cs);
#else
*csport |= cspinmask;
#endif
#endif
if (hwSPI) spi_end();
} }
@ -675,9 +670,7 @@ uint8_t Adafruit_ILI9341::spiread(void) {
SPI.setDataMode(SPI_MODE0); SPI.setDataMode(SPI_MODE0);
r = SPI.transfer(0x00); r = SPI.transfer(0x00);
#else #else
spi_begin();
r = SPI.transfer(0x00); r = SPI.transfer(0x00);
spi_end();
#endif #endif
} else { } else {
#ifndef ESP8266 #ifndef ESP8266
@ -695,40 +688,40 @@ uint8_t Adafruit_ILI9341::spiread(void) {
return r; return r;
} }
uint8_t Adafruit_ILI9341::readdata(void) { uint8_t Adafruit_ILI9341::readdata(void) {
digitalWrite(_dc, HIGH); if(hwSPI) spi_begin();
digitalWrite(_cs, LOW); spiCsLow();
uint8_t r = spiread(); spiDcLow();
digitalWrite(_cs, HIGH); uint8_t r = spiread();
spiCsHigh();
return r; if(hwSPI) spi_end();
return r;
} }
uint8_t Adafruit_ILI9341::readcommand8(uint8_t c, uint8_t index) { uint8_t Adafruit_ILI9341::readcommand8(uint8_t c, uint8_t index) {
if (hwSPI) spi_begin(); if(hwSPI) spi_begin();
digitalWrite(_dc, LOW); // command
digitalWrite(_cs, LOW); spiCsLow();
spiwrite(0xD9); // woo sekret command? spiDcLow();
digitalWrite(_dc, HIGH); // data
spiwrite(0x10 + index); spiwrite(0xD9); // woo sekret command?
digitalWrite(_cs, HIGH); spiDcHigh();
spiwrite(0x10 + index);
digitalWrite(_dc, LOW);
#ifndef ESP8266 #ifndef ESP8266
digitalWrite(_sclk, LOW); digitalWrite(_sclk, LOW);
#endif #endif
digitalWrite(_cs, LOW);
spiwrite(c); spiDcLow();
spiwrite(c);
digitalWrite(_dc, HIGH);
uint8_t r = spiread(); spiDcHigh();
digitalWrite(_cs, HIGH); uint8_t r = spiread();
if (hwSPI) spi_end(); spiCsHigh();
return r;
if(hwSPI) spi_end();
return r;
} }
/* /*

View File

@ -110,7 +110,12 @@
#define ILI9341_GREENYELLOW 0xAFE5 /* 173, 255, 47 */ #define ILI9341_GREENYELLOW 0xAFE5 /* 173, 255, 47 */
#define ILI9341_PINK 0xF81F #define ILI9341_PINK 0xF81F
//#define USE_DIGITAL_WRITE //#define ILI9341_USE_DIGITAL_WRITE
//#define ILI9341_USE_NO_CS
#ifdef ESP8266
//not working
//#define ILI9341_USE_HW_CS
#endif
class Adafruit_ILI9341 : public Adafruit_GFX { class Adafruit_ILI9341 : public Adafruit_GFX {
@ -119,8 +124,11 @@ class Adafruit_ILI9341 : public Adafruit_GFX {
Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK, Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK,
int8_t _RST, int8_t _MISO); int8_t _RST, int8_t _MISO);
#endif #endif
#if defined(USE_HW_CS) || defined(USE_NO_CS)
Adafruit_ILI9341(int8_t _DC, int8_t _RST = -1);
#else
Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _RST = -1); Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _RST = -1);
#endif
void begin(void), void begin(void),
setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1), setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1),
pushColor(uint16_t color), pushColor(uint16_t color),
@ -134,25 +142,51 @@ class Adafruit_ILI9341 : public Adafruit_GFX {
invertDisplay(boolean i); invertDisplay(boolean i);
uint16_t color565(uint8_t r, uint8_t g, uint8_t b); uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
/* These are not for current use, 8-bit protocol only! */ void commandList(uint8_t *addr);
uint8_t readdata(void),
readcommand8(uint8_t reg, uint8_t index = 0);
/*
uint16_t readcommand16(uint8_t);
uint32_t readcommand32(uint8_t);
void dummyclock(void);
*/
void spiwrite(uint8_t), /* These are not for current use, 8-bit protocol only! */
writecommand(uint8_t c), uint8_t readdata(void),
writedata(uint8_t d), readcommand8(uint8_t reg, uint8_t index = 0);
commandList(uint8_t *addr); /*
uint8_t spiread(void); uint16_t readcommand16(uint8_t);
uint32_t readcommand32(uint8_t);
void dummyclock(void);
*/
void writecommand(uint8_t c);
void writedata(uint8_t d);
void writedata(uint8_t * data, uint8_t size);
void writeCmdData(uint8_t cmd, uint8_t * data, uint8_t size);
private: private:
uint8_t tabcolor;
uint8_t spiread(void);
#ifdef ESP8266
inline void spiwrite(uint8_t data);
inline void spiwrite16(uint16_t data);
inline void spiwriteBytes(uint8_t * data, uint8_t size);
inline void spiwritePattern(uint8_t * data, uint8_t size, uint32_t repeat);
inline void setAddrWindow_(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
#else
void spiwrite(uint8_t);
void spiwrite16(uint16_t data);
void spiwriteBytes(uint8_t * data, uint8_t size);
void spiwritePattern(uint8_t * data, uint8_t size, uint8_t repeat);
void setAddrWindow_(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
#endif
inline void spiCsHigh(void);
inline void spiCsLow(void);
inline void spiDcHigh(void);
inline void spiDcLow(void);
uint8_t tabcolor;
#ifndef ESP8266
boolean hwSPI; boolean hwSPI;
#endif
#if defined (__AVR__) || defined(TEENSYDUINO) #if defined (__AVR__) || defined(TEENSYDUINO)
uint8_t mySPCR; uint8_t mySPCR;
volatile uint8_t *mosiport, *clkport, *dcport, *rsport, *csport; volatile uint8_t *mosiport, *clkport, *dcport, *rsport, *csport;
@ -163,7 +197,12 @@ class Adafruit_ILI9341 : public Adafruit_GFX {
uint32_t _cs, _dc, _rst, _mosi, _miso, _sclk; uint32_t _cs, _dc, _rst, _mosi, _miso, _sclk;
uint32_t mosipinmask, clkpinmask, cspinmask, dcpinmask; uint32_t mosipinmask, clkpinmask, cspinmask, dcpinmask;
#elif defined (ESP8266) #elif defined (ESP8266)
uint32_t _cs, _dc, _rst; #ifndef USE_HW_CS
int8_t _cs;
uint32_t _csMask;
#endif
int8_t _dc, _rst;
uint32_t _dcMask, _rstMask;
#endif #endif
}; };

View File

@ -345,8 +345,6 @@ boolean SDClass::begin(uint8_t csPin, uint32_t speed) {
root.openRoot(volume); root.openRoot(volume);
} }
// this little helper is used to traverse paths // this little helper is used to traverse paths
SdFile SDClass::getParentDir(const char *filepath, int *index) { SdFile SDClass::getParentDir(const char *filepath, int *index) {
// get parent directory // get parent directory

View File

@ -66,7 +66,7 @@ public:
// This needs to be called to set up the connection to the SD card // This needs to be called to set up the connection to the SD card
// before other methods are used. // before other methods are used.
boolean begin(uint8_t csPin = SD_CHIP_SELECT_PIN, uint32_t speed = SPI_HALF_SPEED); boolean begin(uint8_t csPin = SD_CHIP_SELECT_PIN, uint32_t speed = SPI_HALF_SPEED);
// Open the specified file/directory with the supplied mode (e.g. read or // Open the specified file/directory with the supplied mode (e.g. read or
// write, etc). Returns a File object for interacting with the file. // write, etc). Returns a File object for interacting with the file.
// Note that currently only one file can be open at a time. // Note that currently only one file can be open at a time.

View File

@ -33,9 +33,13 @@ static void spiSend(uint8_t b) {
SPDR = b; SPDR = b;
while (!(SPSR & (1 << SPIF))) while (!(SPSR & (1 << SPIF)))
; ;
#else
#ifdef ESP8266
SPI.write(b);
#else #else
SPI.transfer(b); SPI.transfer(b);
#endif #endif
#endif
} }
/** Receive a byte from the card */ /** Receive a byte from the card */
static uint8_t spiRec(void) { static uint8_t spiRec(void) {
@ -116,8 +120,14 @@ uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
// send command // send command
spiSend(cmd | 0x40); spiSend(cmd | 0x40);
#ifdef ESP8266
// send argument
SPI.write32(arg, true);
#else
// send argument // send argument
for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s); for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s);
#endif
// send CRC // send CRC
uint8_t crc = 0xFF; uint8_t crc = 0xFF;
@ -424,7 +434,14 @@ uint8_t Sd2Card::readData(uint32_t block,
dst[n] = SPDR; dst[n] = SPDR;
#else // OPTIMIZE_HARDWARE_SPI #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 // skip data before offset
for (;offset_ < offset; offset_++) { for (;offset_ < offset; offset_++) {
spiRec(); spiRec();
@ -433,6 +450,7 @@ uint8_t Sd2Card::readData(uint32_t block,
for (uint16_t i = 0; i < count; i++) { for (uint16_t i = 0; i < count; i++) {
dst[i] = spiRec(); dst[i] = spiRec();
} }
#endif
#endif // OPTIMIZE_HARDWARE_SPI #endif // OPTIMIZE_HARDWARE_SPI
offset_ += count; offset_ += count;
@ -463,7 +481,11 @@ void Sd2Card::readEnd(void) {
while (!(SPSR & (1 << SPIF))) while (!(SPSR & (1 << SPIF)))
; ;
#else // OPTIMIZE_HARDWARE_SPI #else // OPTIMIZE_HARDWARE_SPI
#ifdef ESP8266
SPI.transferBytes(NULL, NULL, (514-offset_));
#else
while (offset_++ < 514) spiRec(); while (offset_++ < 514) spiRec();
#endif
#endif // OPTIMIZE_HARDWARE_SPI #endif // OPTIMIZE_HARDWARE_SPI
chipSelectHigh(); chipSelectHigh();
inBlock_ = 0; inBlock_ = 0;
@ -479,7 +501,11 @@ uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) {
} }
if (!waitStartBlock()) goto fail; if (!waitStartBlock()) goto fail;
// transfer data // transfer data
#ifdef ESP8266
SPI.transferBytes(NULL, dst, 16);
#else
for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec(); for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec();
#endif
spiRec(); // get first crc byte spiRec(); // get first crc byte
spiRec(); // get second crc byte spiRec(); // get second crc byte
chipSelectHigh(); chipSelectHigh();
@ -646,13 +672,21 @@ uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) {
#else // OPTIMIZE_HARDWARE_SPI #else // OPTIMIZE_HARDWARE_SPI
spiSend(token); spiSend(token);
#ifdef ESP8266
// send argument
SPI.writeBytes((uint8_t *)src, 512);
#else
for (uint16_t i = 0; i < 512; i++) { for (uint16_t i = 0; i < 512; i++) {
spiSend(src[i]); spiSend(src[i]);
} }
#endif
#endif // OPTIMIZE_HARDWARE_SPI #endif // OPTIMIZE_HARDWARE_SPI
#ifdef ESP8266
SPI.write16(0xFFFF, true);
#else
spiSend(0xff); // dummy crc spiSend(0xff); // dummy crc
spiSend(0xff); // dummy crc spiSend(0xff); // dummy crc
#endif
status_ = spiRec(); status_ = spiRec();
if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
error(SD_CARD_ERROR_WRITE); error(SD_CARD_ERROR_WRITE);