mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-16 11:21:18 +03:00
@ -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) {
|
||||||
|
@ -69,6 +69,5 @@ void setup(void){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loop(void){
|
void loop(void){
|
||||||
mdns.update();
|
|
||||||
server.handleClient();
|
server.handleClient();
|
||||||
}
|
}
|
||||||
|
@ -308,6 +308,5 @@ void setup(void){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loop(void){
|
void loop(void){
|
||||||
//mdns.update();
|
|
||||||
server.handleClient();
|
server.handleClient();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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) {
|
||||||
|
@ -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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user