From e8fd4e50f31ceb7afc532f5310cb363c8204e673 Mon Sep 17 00:00:00 2001 From: Nat Date: Fri, 7 Oct 2016 13:10:13 +0700 Subject: [PATCH 01/33] Add Nano32 --- boards.txt | 41 ++++++++++++++++++++++++++++++++++ variants/nano32/pins_arduino.h | 35 +++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 variants/nano32/pins_arduino.h diff --git a/boards.txt b/boards.txt index 3835d5c38fd..067cffe3096 100644 --- a/boards.txt +++ b/boards.txt @@ -40,3 +40,44 @@ esp32.menu.UploadSpeed.460800.macosx=460800 esp32.menu.UploadSpeed.460800.upload.speed=460800 esp32.menu.UploadSpeed.512000.windows=512000 esp32.menu.UploadSpeed.512000.upload.speed=512000 + + +############################################################## +nano32.name=Nano32 + +nano32.upload.tool=esptool +nano32.upload.maximum_size=1044464 +nano32.upload.maximum_data_size=114688 +nano32.upload.wait_for_upload_port=true + +nano32.serial.disableDTR=true +nano32.serial.disableRTS=true + +nano32.build.mcu=esp32 +nano32.build.core=esp32 +nano32.build.variant=nano32 +nano32.build.board=NANO32 + +nano32.build.f_cpu=160000000L +nano32.build.flash_mode=dio +nano32.build.flash_size=4MB + +nano32.menu.FlashFreq.80=80MHz +nano32.menu.FlashFreq.80.build.flash_freq=80m +nano32.menu.FlashFreq.40=40MHz +nano32.menu.FlashFreq.40.build.flash_freq=40m + +nano32.menu.UploadSpeed.921600=921600 +nano32.menu.UploadSpeed.921600.upload.speed=921600 +nano32.menu.UploadSpeed.115200=115200 +nano32.menu.UploadSpeed.115200.upload.speed=115200 +nano32.menu.UploadSpeed.256000.windows=256000 +nano32.menu.UploadSpeed.256000.upload.speed=256000 +nano32.menu.UploadSpeed.230400.windows.upload.speed=256000 +nano32.menu.UploadSpeed.230400=230400 +nano32.menu.UploadSpeed.230400.upload.speed=230400 +nano32.menu.UploadSpeed.460800.linux=460800 +nano32.menu.UploadSpeed.460800.macosx=460800 +nano32.menu.UploadSpeed.460800.upload.speed=460800 +nano32.menu.UploadSpeed.512000.windows=512000 +nano32.menu.UploadSpeed.512000.upload.speed=512000 diff --git a/variants/nano32/pins_arduino.h b/variants/nano32/pins_arduino.h new file mode 100644 index 00000000000..0c2dbc0d8ac --- /dev/null +++ b/variants/nano32/pins_arduino.h @@ -0,0 +1,35 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + + +#define digitalPinToPort(pin) (0) +#define digitalPinToBitMask(pin) (1UL << (pin)) +#define digitalPinToTimer(pin) (0) +#define portOutputRegister(port) +#define portInputRegister(port) +#define portModeRegister(port) + +#define NOT_A_PIN -1 +#define NOT_A_PORT -1 +#define NOT_AN_INTERRUPT -1 +#define NOT_ON_TIMER 0 + +#define EXTERNAL_NUM_INTERRUPTS 16 +#define NUM_DIGITAL_PINS 38 +#define NUM_ANALOG_INPUTS 18 + +#define analogInputToDigitalPin(p) +#define digitalPinToInterrupt(p) +#define digitalPinHasPWM(p) + +#define LED_BUILTIN 16 + +static const uint8_t SDA = 21; +static const uint8_t SCL = 22; + +static const uint8_t SS = 2; +static const uint8_t MOSI = 23; +static const uint8_t MISO = 19; +static const uint8_t SCK = 18; + +#endif /* Pins_Arduino_h */ \ No newline at end of file From c9c3e78bba6caafef089b1de04eab4686dc303d5 Mon Sep 17 00:00:00 2001 From: Nat Date: Tue, 18 Oct 2016 10:32:24 +0700 Subject: [PATCH 02/33] Change upload.maximum_data_size to 294912 --- boards.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards.txt b/boards.txt index 067cffe3096..e1433716bd0 100644 --- a/boards.txt +++ b/boards.txt @@ -47,7 +47,7 @@ nano32.name=Nano32 nano32.upload.tool=esptool nano32.upload.maximum_size=1044464 -nano32.upload.maximum_data_size=114688 +nano32.upload.maximum_data_size=294912 nano32.upload.wait_for_upload_port=true nano32.serial.disableDTR=true From 7eee62e8fa5f535066978b1bb40855bb90ea994b Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Fri, 7 Oct 2016 11:32:35 +0300 Subject: [PATCH 03/33] Update README.md --- README.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c12ecbb398e..e7523f41907 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,26 @@ Arduino core for ESP32 WiFi chip =========================================== +### Development Status +Not everything is working yet, you can not get it through package manager, but you can give it a go and help us find bugs in the things that are implemented :) + +The framework can also be downloaded as component in an IDF project and be used like that. + +Things that "should" work: +- pinMode +- digitalRead/digitalWrite +- attachInterrupt/detachInterrupt +- Serial (global Serial is attached to pins 1 and 3 by default, there are another 2 serials that you can attach to any pin) +- SPI (global SPI is attached to VSPI pins by default and HSPI can be attached to any pins) +- Wire (global Wire is attached to pins 21 and 22 by default and there is another I2C bus that you can attach to any pins) +- WiFi (about 99% the same as ESP8266) + +WiFiClient, WiFiServer and WiFiUdp are not quite ready yet because there are still some small hiccups in LwIP to be overcome. +You can try WiFiClient but you need to disconnect the client yourself to be sure that connection is closed. + ### Installation -- Install Arduino 1.6.9 -- Go to Arduino directory +- Install Arduino IDE +- Go to Arduino IDE installation directory - Clone this repository into hardware/espressif/esp32 directory (or clone it elsewhere and create a symlink) ```bash cd hardware From 6243347036b6a95750011f896e2937b49ba76545 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Fri, 7 Oct 2016 23:31:49 +0300 Subject: [PATCH 04/33] include math.h by default --- cores/esp32/esp32-hal.h | 1 + 1 file changed, 1 insertion(+) diff --git a/cores/esp32/esp32-hal.h b/cores/esp32/esp32-hal.h index 826fa62b23c..4433078e95f 100644 --- a/cores/esp32/esp32-hal.h +++ b/cores/esp32/esp32-hal.h @@ -30,6 +30,7 @@ extern "C" { #include #include #include +#include #define ESP_REG(addr) *((volatile uint32_t *)(addr)) #define NOP() asm volatile ("nop") From 3a7ce7e573285602de76901644e7af3ecb73443b Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 7 Oct 2016 23:56:50 +0300 Subject: [PATCH 05/33] fix F macro --- cores/esp32/WString.h | 6 ++---- cores/esp32/pgmspace.h | 3 ++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cores/esp32/WString.h b/cores/esp32/WString.h index 604763aa36c..d99352f4d74 100644 --- a/cores/esp32/WString.h +++ b/cores/esp32/WString.h @@ -26,7 +26,7 @@ #include #include #include -//#include +#include // An inherited class for holding the result of a concatenation. These // result objects are assumed to be writable by subsequent concatenations. @@ -34,9 +34,7 @@ class StringSumHelper; // an abstract class used as a means to proide a unique pointer type // but really has no body -class __FlashStringHelper; -#define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer)) -#define F(string_literal) (FPSTR(PSTR(string_literal))) +//class __FlashStringHelper; // The string class class String diff --git a/cores/esp32/pgmspace.h b/cores/esp32/pgmspace.h index ce1553918b6..013ff63cea6 100644 --- a/cores/esp32/pgmspace.h +++ b/cores/esp32/pgmspace.h @@ -22,7 +22,8 @@ typedef char __FlashStringHelper; #define PROGMEM #define PSTR(s) (s) -#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) +#define FPSTR(pstr_pointer) ((const char *)(pstr_pointer)) +#define F(string_literal) (string_literal) #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define pgm_read_word(addr) (*(const unsigned short *)(addr)) From 9c6fdfaaf1b74e448878faabd873d72e987a28fa Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 7 Oct 2016 23:59:24 +0300 Subject: [PATCH 06/33] comment out __FlashStringHelper methods in Print --- cores/esp32/Print.cpp | 4 ++-- cores/esp32/Print.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cores/esp32/Print.cpp b/cores/esp32/Print.cpp index b37d5269cc3..035acf01422 100644 --- a/cores/esp32/Print.cpp +++ b/cores/esp32/Print.cpp @@ -128,14 +128,14 @@ size_t Print::print(double n, int digits) { return printFloat(n, digits); } - +/* size_t Print::println(const __FlashStringHelper *ifsh) { size_t n = print(ifsh); n += println(); return n; } - +*/ size_t Print::print(const Printable& x) { return x.printTo(*this); diff --git a/cores/esp32/Print.h b/cores/esp32/Print.h index 49867289bfe..b792799dd9c 100644 --- a/cores/esp32/Print.h +++ b/cores/esp32/Print.h @@ -72,7 +72,7 @@ class Print } size_t printf(const char * format, ...) __attribute__ ((format (printf, 2, 3))); - size_t print(const __FlashStringHelper *); + //size_t print(const __FlashStringHelper *); size_t print(const String &); size_t print(const char[]); size_t print(char); @@ -84,7 +84,7 @@ class Print size_t print(double, int = 2); size_t print(const Printable&); - size_t println(const __FlashStringHelper *); + //size_t println(const __FlashStringHelper *); size_t println(const String &s); size_t println(const char[]); size_t println(char); From 6ddf4b6ce28f734a25ef20a1e0a32006b9274939 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Sat, 8 Oct 2016 00:18:12 +0300 Subject: [PATCH 07/33] Print::printf should allocate it's buffer --- cores/esp32/Print.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cores/esp32/Print.cpp b/cores/esp32/Print.cpp index 035acf01422..34584c50e43 100644 --- a/cores/esp32/Print.cpp +++ b/cores/esp32/Print.cpp @@ -46,14 +46,18 @@ size_t Print::write(const uint8_t *buffer, size_t size) size_t Print::printf(const char *format, ...) { + char * temp; va_list arg; va_start(arg, format); size_t len = vsnprintf(NULL, 0, format, arg); - char temp[len+1]; - uint8_t * stemp = (uint8_t*)temp; + temp = new char[len+1]; + if(temp == NULL) { + return 0; + } len = vsnprintf(temp, len+1, format, arg); - write(stemp, len); + write((uint8_t*)temp, len); va_end(arg); + delete[] temp; return len; } /* From d9271d48b136a5ffdede376e4b5526273a49d313 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Sat, 8 Oct 2016 00:40:11 +0300 Subject: [PATCH 08/33] add more definitions to pgmspace.h to match ESP8266 --- cores/esp32/pgmspace.h | 64 +++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/cores/esp32/pgmspace.h b/cores/esp32/pgmspace.h index 013ff63cea6..6e10d926ea5 100644 --- a/cores/esp32/pgmspace.h +++ b/cores/esp32/pgmspace.h @@ -19,25 +19,61 @@ #ifndef PGMSPACE_INCLUDE #define PGMSPACE_INCLUDE +typedef void prog_void; +typedef char prog_char; +typedef unsigned char prog_uchar; +typedef char prog_int8_t; +typedef unsigned char prog_uint8_t; +typedef short prog_int16_t; +typedef unsigned short prog_uint16_t; +typedef long prog_int32_t; +typedef unsigned long prog_uint32_t; + typedef char __FlashStringHelper; + +#define SIZE_IRRELEVANT 0x7fffffff + #define PROGMEM -#define PSTR(s) (s) -#define FPSTR(pstr_pointer) ((const char *)(pstr_pointer)) -#define F(string_literal) (string_literal) +#define PGM_P const char * +#define PGM_VOID_P const void * +#define FPSTR(p) ((const char *)(p)) +#define PSTR(s) (s) +#define F(s) (s) +#define _SFR_BYTE(n) (n) -#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) -#define pgm_read_word(addr) (*(const unsigned short *)(addr)) -#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) -#define pgm_read_float(addr) (*(const float *)(addr)) +#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#define pgm_read_word(addr) (*(const unsigned short *)(addr)) +#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) +#define pgm_read_float(addr) (*(const float *)(addr)) -#define pgm_read_byte_near(addr) pgm_read_byte(addr) -#define pgm_read_word_near(addr) pgm_read_word(addr) +#define pgm_read_byte_near(addr) pgm_read_byte(addr) +#define pgm_read_word_near(addr) pgm_read_word(addr) #define pgm_read_dword_near(addr) pgm_read_dword(addr) #define pgm_read_float_near(addr) pgm_read_float(addr) -#define pgm_read_byte_far(addr) pgm_read_byte(addr) -#define pgm_read_word_far(addr) pgm_read_word(addr) -#define pgm_read_dword_far(addr) pgm_read_dword(addr) -#define pgm_read_float_far(addr) pgm_read_float(addr) +#define pgm_read_byte_far(addr) pgm_read_byte(addr) +#define pgm_read_word_far(addr) pgm_read_word(addr) +#define pgm_read_dword_far(addr) pgm_read_dword(addr) +#define pgm_read_float_far(addr) pgm_read_float(addr) + +#define memcmp_P memcmp +#define memccpy_P memccpy +#define memmem_P memmem +#define memcpy_P memcpy +#define strncpy_P strncpy +#define strncat_P strncat +#define strncmp_P strncmp +#define strncasecmp_P strncasecmp +#define strnlen_P strnlen +#define strstr_P strstr +#define printf_P printf +#define sprintf_P sprintf +#define snprintf_P snprintf +#define vsnprintf_P vsnprintf + +#define strlen_P(strP) strnlen_P((strP), SIZE_IRRELEVANT) +#define strcasecmp_P(str1, str2P) strncasecmp_P((str1), (str2P), SIZE_IRRELEVANT) +#define strcmp_P(str1, str2P) strncmp_P((str1), (str2P), SIZE_IRRELEVANT) +#define strcat_P(dest, src) strncat_P((dest), (src), SIZE_IRRELEVANT) +#define strcpy_P(dest, src) strncpy_P((dest), (src), SIZE_IRRELEVANT) -#define memcpy_P(to,from,len) memcpy(to,from,len) #endif From 08fb11f7fc4d7c3fcd9f83c5f3d1405f6f4d3bd8 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Sat, 8 Oct 2016 13:09:54 +0300 Subject: [PATCH 09/33] Remove non-working WiFi examples and fix some that require changes --- .../examples/HTTPSRequest/HTTPSRequest.ino | 90 ----------- .../WiFi/examples/NTPClient/NTPClient.ino | 152 ------------------ .../WiFiAccessPoint/WiFiAccessPoint.ino | 71 -------- .../WiFiClientEvents/WiFiClientEvents.ino | 4 +- libraries/WiFi/examples/WiFiScan/WiFiScan.ino | 2 +- .../WiFiTelnetToSerial/WiFiTelnetToSerial.ino | 103 ------------ .../examples/WiFiWebServer/WiFiWebServer.ino | 100 ------------ 7 files changed, 3 insertions(+), 519 deletions(-) delete mode 100644 libraries/WiFi/examples/HTTPSRequest/HTTPSRequest.ino delete mode 100644 libraries/WiFi/examples/NTPClient/NTPClient.ino delete mode 100644 libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino delete mode 100644 libraries/WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino delete mode 100644 libraries/WiFi/examples/WiFiWebServer/WiFiWebServer.ino diff --git a/libraries/WiFi/examples/HTTPSRequest/HTTPSRequest.ino b/libraries/WiFi/examples/HTTPSRequest/HTTPSRequest.ino deleted file mode 100644 index 56294d08c22..00000000000 --- a/libraries/WiFi/examples/HTTPSRequest/HTTPSRequest.ino +++ /dev/null @@ -1,90 +0,0 @@ -/* - * HTTP over TLS (HTTPS) example sketch - * - * This example demonstrates how to use - * WiFiClientSecure class to access HTTPS API. - * We fetch and display the status of - * esp8266/Arduino project continuous integration - * build. - * - * Created by Ivan Grokhotkov, 2015. - * This example is in public domain. - */ - -#include -#include - -const char* ssid = "........"; -const char* password = "........"; - -const char* host = "api.github.com"; -const int httpsPort = 443; - -// Use web browser to view and copy -// SHA1 fingerprint of the certificate -const char* fingerprint = "CF 05 98 89 CA FF 8E D8 5E 5C E0 C2 E4 F7 E6 C3 C7 50 DD 5C"; - -void setup() -{ - Serial.begin(115200); - Serial.println(); - Serial.print("connecting to "); - Serial.println(ssid); - WiFi.begin(ssid, password); - while (WiFi.status() != WL_CONNECTED) { - delay(500); - Serial.print("."); - } - Serial.println(""); - Serial.println("WiFi connected"); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - - // Use WiFiClientSecure class to create TLS connection - WiFiClientSecure client; - Serial.print("connecting to "); - Serial.println(host); - if (!client.connect(host, httpsPort)) { - Serial.println("connection failed"); - return; - } - - if (client.verify(fingerprint, host)) { - Serial.println("certificate matches"); - } else { - Serial.println("certificate doesn't match"); - } - - String url = "/repos/esp8266/Arduino/commits/master/status"; - Serial.print("requesting URL: "); - Serial.println(url); - - client.print(String("GET ") + url + " HTTP/1.1\r\n" + - "Host: " + host + "\r\n" + - "User-Agent: BuildFailureDetectorESP8266\r\n" + - "Connection: close\r\n\r\n"); - - Serial.println("request sent"); - while (client.connected()) { - String line = client.readStringUntil('\n'); - if (line == "\r") { - Serial.println("headers received"); - break; - } - } - String line = client.readStringUntil('\n'); - if (line.startsWith("{\"state\":\"success\"")) { - Serial.println("esp8266/Arduino CI successfull!"); - } else { - Serial.println("esp8266/Arduino CI has failed"); - } - Serial.println("reply was:"); - Serial.println("=========="); - Serial.println(line); - Serial.println("=========="); - Serial.println("closing connection"); -} - -void loop() -{ -} diff --git a/libraries/WiFi/examples/NTPClient/NTPClient.ino b/libraries/WiFi/examples/NTPClient/NTPClient.ino deleted file mode 100644 index 004d4566477..00000000000 --- a/libraries/WiFi/examples/NTPClient/NTPClient.ino +++ /dev/null @@ -1,152 +0,0 @@ -/* - - Udp NTP Client - - Get the time from a Network Time Protocol (NTP) time server - Demonstrates use of UDP sendPacket and ReceivePacket - For more on NTP time servers and the messages needed to communicate with them, - see http://en.wikipedia.org/wiki/Network_Time_Protocol - - created 4 Sep 2010 - by Michael Margolis - modified 9 Apr 2012 - by Tom Igoe - updated for the ESP8266 12 Apr 2015 - by Ivan Grokhotkov - - This code is in the public domain. - - */ - -#include -#include - -char ssid[] = "*************"; // your network SSID (name) -char pass[] = "********"; // your network password - - -unsigned int localPort = 2390; // local port to listen for UDP packets - -/* Don't hardwire the IP address or we won't get the benefits of the pool. - * Lookup the IP address for the host name instead */ -//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server -IPAddress timeServerIP; // time.nist.gov NTP server address -const char* ntpServerName = "time.nist.gov"; - -const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message - -byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets - -// A UDP instance to let us send and receive packets over UDP -WiFiUDP udp; - -void setup() -{ - Serial.begin(115200); - Serial.println(); - Serial.println(); - - // We start by connecting to a WiFi network - Serial.print("Connecting to "); - Serial.println(ssid); - WiFi.begin(ssid, pass); - - while (WiFi.status() != WL_CONNECTED) { - delay(500); - Serial.print("."); - } - Serial.println(""); - - Serial.println("WiFi connected"); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - - Serial.println("Starting UDP"); - udp.begin(localPort); - Serial.print("Local port: "); - Serial.println(udp.localPort()); -} - -void loop() -{ - //get a random server from the pool - WiFi.hostByName(ntpServerName, timeServerIP); - - sendNTPpacket(timeServerIP); // send an NTP packet to a time server - // wait to see if a reply is available - delay(1000); - - int cb = udp.parsePacket(); - if (!cb) { - Serial.println("no packet yet"); - } else { - Serial.print("packet received, length="); - Serial.println(cb); - // We've received a packet, read the data from it - udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer - - //the timestamp starts at byte 40 of the received packet and is four bytes, - // or two words, long. First, esxtract the two words: - - unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); - unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); - // combine the four bytes (two words) into a long integer - // this is NTP time (seconds since Jan 1 1900): - unsigned long secsSince1900 = highWord << 16 | lowWord; - Serial.print("Seconds since Jan 1 1900 = " ); - Serial.println(secsSince1900); - - // now convert NTP time into everyday time: - Serial.print("Unix time = "); - // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: - const unsigned long seventyYears = 2208988800UL; - // subtract seventy years: - unsigned long epoch = secsSince1900 - seventyYears; - // print Unix time: - Serial.println(epoch); - - - // print the hour, minute and second: - Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT) - Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day) - Serial.print(':'); - if ( ((epoch % 3600) / 60) < 10 ) { - // In the first 10 minutes of each hour, we'll want a leading '0' - Serial.print('0'); - } - Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute) - Serial.print(':'); - if ( (epoch % 60) < 10 ) { - // In the first 10 seconds of each minute, we'll want a leading '0' - Serial.print('0'); - } - Serial.println(epoch % 60); // print the second - } - // wait ten seconds before asking for the time again - delay(10000); -} - -// send an NTP request to the time server at the given address -unsigned long sendNTPpacket(IPAddress& address) -{ - Serial.println("sending NTP packet..."); - // set all bytes in the buffer to 0 - memset(packetBuffer, 0, NTP_PACKET_SIZE); - // Initialize values needed to form NTP request - // (see URL above for details on the packets) - packetBuffer[0] = 0b11100011; // LI, Version, Mode - packetBuffer[1] = 0; // Stratum, or type of clock - packetBuffer[2] = 6; // Polling Interval - packetBuffer[3] = 0xEC; // Peer Clock Precision - // 8 bytes of zero for Root Delay & Root Dispersion - packetBuffer[12] = 49; - packetBuffer[13] = 0x4E; - packetBuffer[14] = 49; - packetBuffer[15] = 52; - - // all NTP fields have been given values, now - // you can send a packet requesting a timestamp: - udp.beginPacket(address, 123); //NTP requests are to port 123 - udp.write(packetBuffer, NTP_PACKET_SIZE); - udp.endPacket(); -} diff --git a/libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino b/libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino deleted file mode 100644 index 9fa6c91f7e2..00000000000 --- a/libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2015, Majenko Technologies - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * * Neither the name of Majenko Technologies nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Create a WiFi access point and provide a web server on it. */ - -#include -#include -#include - -/* Set these to your desired credentials. */ -const char *ssid = "ESPap"; -const char *password = "thereisnospoon"; - -ESP8266WebServer server(80); - -/* Just a little test message. Go to http://192.168.4.1 in a web browser - * connected to this access point to see it. - */ -void handleRoot() -{ - server.send(200, "text/html", "

You are connected

"); -} - -void setup() -{ - delay(1000); - Serial.begin(115200); - Serial.println(); - Serial.print("Configuring access point..."); - /* You can remove the password parameter if you want the AP to be open. */ - WiFi.softAP(ssid, password); - - IPAddress myIP = WiFi.softAPIP(); - Serial.print("AP IP address: "); - Serial.println(myIP); - server.on("/", handleRoot); - server.begin(); - Serial.println("HTTP server started"); -} - -void loop() -{ - server.handleClient(); -} diff --git a/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino b/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino index b6842cd46a2..6971e269be0 100644 --- a/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino +++ b/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino @@ -14,12 +14,12 @@ void WiFiEvent(WiFiEvent_t event) Serial.printf("[WiFi-event] event: %d\n", event); switch(event) { - case WIFI_EVENT_STAMODE_GOT_IP: + case SYSTEM_EVENT_STA_GOT_IP: Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); break; - case WIFI_EVENT_STAMODE_DISCONNECTED: + case SYSTEM_EVENT_STA_DISCONNECTED: Serial.println("WiFi lost connection"); break; } diff --git a/libraries/WiFi/examples/WiFiScan/WiFiScan.ino b/libraries/WiFi/examples/WiFiScan/WiFiScan.ino index 975a1fe62b8..5d11fbb6926 100644 --- a/libraries/WiFi/examples/WiFiScan/WiFiScan.ino +++ b/libraries/WiFi/examples/WiFiScan/WiFiScan.ino @@ -37,7 +37,7 @@ void loop() Serial.print(" ("); Serial.print(WiFi.RSSI(i)); Serial.print(")"); - Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*"); + Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*"); delay(10); } } diff --git a/libraries/WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino b/libraries/WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino deleted file mode 100644 index 4099928e40d..00000000000 --- a/libraries/WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino +++ /dev/null @@ -1,103 +0,0 @@ -/* - WiFiTelnetToSerial - Example Transparent UART to Telnet Server for esp8266 - - Copyright (c) 2015 Hristo Gochkov. All rights reserved. - This file is part of the WiFi library for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#include - -//how many clients should be able to telnet to this ESP8266 -#define MAX_SRV_CLIENTS 1 -const char* ssid = "**********"; -const char* password = "**********"; - -WiFiServer server(23); -WiFiClient serverClients[MAX_SRV_CLIENTS]; - -void setup() -{ - Serial1.begin(115200); - WiFi.begin(ssid, password); - Serial1.print("\nConnecting to "); - Serial1.println(ssid); - uint8_t i = 0; - while (WiFi.status() != WL_CONNECTED && i++ < 20) { - delay(500); - } - if(i == 21) { - Serial1.print("Could not connect to"); - Serial1.println(ssid); - while(1) { - delay(500); - } - } - //start UART and the server - Serial.begin(115200); - server.begin(); - server.setNoDelay(true); - - Serial1.print("Ready! Use 'telnet "); - Serial1.print(WiFi.localIP()); - Serial1.println(" 23' to connect"); -} - -void loop() -{ - uint8_t i; - //check if there are any new clients - if (server.hasClient()) { - for(i = 0; i < MAX_SRV_CLIENTS; i++) { - //find free/disconnected spot - if (!serverClients[i] || !serverClients[i].connected()) { - if(serverClients[i]) { - serverClients[i].stop(); - } - serverClients[i] = server.available(); - Serial1.print("New client: "); - Serial1.print(i); - continue; - } - } - //no free/disconnected spot so reject - WiFiClient serverClient = server.available(); - serverClient.stop(); - } - //check clients for data - for(i = 0; i < MAX_SRV_CLIENTS; i++) { - if (serverClients[i] && serverClients[i].connected()) { - if(serverClients[i].available()) { - //get data from the telnet client and push it to the UART - while(serverClients[i].available()) { - Serial.write(serverClients[i].read()); - } - } - } - } - //check UART for data - if(Serial.available()) { - size_t len = Serial.available(); - uint8_t sbuf[len]; - Serial.readBytes(sbuf, len); - //push UART data to all connected telnet clients - for(i = 0; i < MAX_SRV_CLIENTS; i++) { - if (serverClients[i] && serverClients[i].connected()) { - serverClients[i].write(sbuf, len); - delay(1); - } - } - } -} diff --git a/libraries/WiFi/examples/WiFiWebServer/WiFiWebServer.ino b/libraries/WiFi/examples/WiFiWebServer/WiFiWebServer.ino deleted file mode 100644 index 91e85b3d0eb..00000000000 --- a/libraries/WiFi/examples/WiFiWebServer/WiFiWebServer.ino +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This sketch demonstrates how to set up a simple HTTP-like server. - * The server will set a GPIO pin depending on the request - * http://server_ip/gpio/0 will set the GPIO2 low, - * http://server_ip/gpio/1 will set the GPIO2 high - * server_ip is the IP address of the ESP8266 module, will be - * printed to Serial when the module is connected. - */ - -#include - -const char* ssid = "your-ssid"; -const char* password = "your-password"; - -// Create an instance of the server -// specify the port to listen on as an argument -WiFiServer server(80); - -void setup() -{ - Serial.begin(115200); - delay(10); - - // prepare GPIO2 - pinMode(2, OUTPUT); - digitalWrite(2, 0); - - // Connect to WiFi network - Serial.println(); - Serial.println(); - Serial.print("Connecting to "); - Serial.println(ssid); - - WiFi.begin(ssid, password); - - while (WiFi.status() != WL_CONNECTED) { - delay(500); - Serial.print("."); - } - Serial.println(""); - Serial.println("WiFi connected"); - - // Start the server - server.begin(); - Serial.println("Server started"); - - // Print the IP address - Serial.println(WiFi.localIP()); -} - -void loop() -{ - // Check if a client has connected - WiFiClient client = server.available(); - if (!client) { - return; - } - - // Wait until the client sends some data - Serial.println("new client"); - while(!client.available()) { - delay(1); - } - - // Read the first line of the request - String req = client.readStringUntil('\r'); - Serial.println(req); - client.flush(); - - // Match the request - int val; - if (req.indexOf("/gpio/0") != -1) { - val = 0; - } else if (req.indexOf("/gpio/1") != -1) { - val = 1; - } else { - Serial.println("invalid request"); - client.stop(); - return; - } - - // Set GPIO2 according to the request - digitalWrite(2, val); - - client.flush(); - - // Prepare the response - String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\n\r\nGPIO is now "; - s += (val)?"high":"low"; - s += "\n"; - - // Send the response to the client - client.print(s); - delay(1); - Serial.println("Client disonnected"); - - // The client will actually be disconnected - // when the function returns and 'client' object is detroyed -} - From 7f398028300c9cb98c0e04b0ec198f75117a1609 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Sat, 8 Oct 2016 17:32:11 +0300 Subject: [PATCH 10/33] fix i2c hal --- cores/esp32/esp32-hal-i2c.c | 112 +++++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 26 deletions(-) diff --git a/cores/esp32/esp32-hal-i2c.c b/cores/esp32/esp32-hal-i2c.c index 40dfac2e440..71c153c0b4c 100644 --- a/cores/esp32/esp32-hal-i2c.c +++ b/cores/esp32/esp32-hal-i2c.c @@ -63,10 +63,10 @@ enum { /* * index - command index (0 to 15) * op_code - is the command + * byte_num - This register is to store the amounts of data that is read and written. byte_num in RSTART, STOP, END is null. * ack_val - Each data byte is terminated by an ACK bit used to set the bit level. * ack_exp - This bit is to set an expected ACK value for the transmitter. * ack_check - This bit is to decide whether the transmitter checks ACK bit. 1 means yes and 0 means no. - * byte_num - This register is to store the amounts of data that is read and written. byte_num in RSTART, STOP, END is null. * */ void i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bool ack_val, bool ack_exp, bool ack_check) { @@ -80,6 +80,7 @@ void i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bo int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop) { + int i; uint8_t index = 0; uint8_t dataLen = len + (addr_10bit?2:1); address = (address << 1); @@ -87,8 +88,11 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin while(dataLen) { uint8_t willSend = (dataLen > 32)?32:dataLen; uint8_t dataSend = willSend; - i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false);//START - i2cSetCmd(i2c, 1, I2C_CMD_WRITE, willSend, false, false, true); + + //CMD START + i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false); + + //CMD WRITE(ADDRESS + DATA) if(!index) { i2c->dev->fifo_data.data = address & 0xFF; dataSend--; @@ -97,27 +101,56 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin dataSend--; } } - int i = 0; + i = 0; while(idev->fifo_data.data = data[index++]; } + i2cSetCmd(i2c, 1, I2C_CMD_WRITE, willSend, false, false, true); dataLen -= willSend; + + //CMD STOP or CMD END if there is more data if(dataLen) { i2cSetCmd(i2c, 2, I2C_CMD_END, 0, false, false, false); } else if(sendStop) { - i2cSetCmd(i2c, 2, I2C_CMD_STOP, 0, false, false, true); + i2cSetCmd(i2c, 2, I2C_CMD_STOP, 0, false, false, false); } + + //Clear Interrupts + i2c->dev->int_clr.val = 0xFFFFFFFF; + + //START Transmission i2c->dev->ctr.trans_start = 1; - while(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || (!i2c->dev->int_raw.ack_err && !i2c->dev->command[2].done)); - if(!i2c->dev->command[2].done) { - log_e("Ack Error"); - return -1; + + //WAIT Transmission + while(1) { + if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[2].done)) { + continue; + } else if(i2c->dev->int_raw.ack_err || i2c->dev->int_raw.time_out || i2c->dev->int_raw.arbitration_lost) { + break; + } else if(i2c->dev->command[2].done) { + break; + } } - if(i2c->dev->status_reg.arb_lost || i2c->dev->status_reg.time_out) { - log_e("Bus Fail"); - return -1; + + //Bus failed (maybe check for this while waiting? + if(i2c->dev->int_raw.arbitration_lost) { + //log_e("Bus Fail! Addr: %x", address >> 1); + return 4; + } + + //Bus timeout + if(i2c->dev->int_raw.time_out) { + //log_e("Bus Timeout! Addr: %x", address >> 1); + return 3; } + + //Transmission did not finish and ACK_ERR is set + if(i2c->dev->int_raw.ack_err) { + //log_e("Ack Error! Addr: %x", address >> 1); + return 1; + } + } return 0; } @@ -130,12 +163,16 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint uint8_t cmdIdx; uint8_t willRead; - i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false);//START - i2cSetCmd(i2c, 1, I2C_CMD_WRITE, addrLen, false, false, true); + //CMD START + i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false); + + //CMD WRITE ADDRESS i2c->dev->fifo_data.data = address & 0xFF; if(addr_10bit) { i2c->dev->fifo_data.data = (address >> 8) & 0xFF; } + i2cSetCmd(i2c, 1, I2C_CMD_WRITE, addrLen, false, false, true); + while(len) { cmdIdx = (index)?0:2; willRead = (len > 32)?32:(len-1); @@ -150,14 +187,38 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint } } + //Clear Interrupts + i2c->dev->int_clr.val = 0xFFFFFFFF; + + //START Transmission i2c->dev->ctr.trans_start = 1; - while(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || (!i2c->dev->int_raw.ack_err && !i2c->dev->command[cmdIdx-1].done)); - if(!i2c->dev->command[cmdIdx-1].done) { - log_e("Ack Error"); - return -1; + + //WAIT Transmission + while(1) { + if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[cmdIdx-1].done)) { + continue; + } else if(i2c->dev->int_raw.ack_err || i2c->dev->int_raw.time_out || i2c->dev->int_raw.arbitration_lost) { + break; + } else if(i2c->dev->command[cmdIdx-1].done) { + break; + } + } + + //Bus failed (maybe check for this while waiting? + if(i2c->dev->int_raw.arbitration_lost) { + //log_e("Bus Fail! Addr: %x", address >> 1); + return -4; + } + + //Bus timeout + if(i2c->dev->int_raw.time_out) { + //log_e("Bus Timeout! Addr: %x", address >> 1); + return -3; } - if(i2c->dev->status_reg.arb_lost || i2c->dev->status_reg.time_out) { - log_e("Bus Fail"); + + //Transmission did not finish and ACK_ERR is set + if(i2c->dev->int_raw.ack_err) { + //log_e("Ack Error! Addr: %x", address >> 1); return -1; } int i = 0; @@ -192,8 +253,8 @@ void i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed) i2c->dev->scl_stop_hold.time = 50; i2c->dev->scl_stop_setup.time = 50; - i2c->dev->sda_hold.time = 40; - i2c->dev->sda_sample.time = 40; + i2c->dev->sda_hold.time = 25; + i2c->dev->sda_sample.time = 25; } uint32_t i2cGetFrequency(i2c_t * i2c) @@ -205,7 +266,6 @@ uint32_t i2cGetFrequency(i2c_t * i2c) * mode - 0 = Slave, 1 = Master * slave_addr - I2C Address * addr_10bit_en - enable slave 10bit address mode. - * clk_speed - SCL Frequency * */ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en) @@ -226,16 +286,16 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en) CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT1_RST); } - i2c->dev->ctr.rx_lsb_first = 0 ; - i2c->dev->ctr.tx_lsb_first = 0 ; + i2c->dev->ctr.val = 0; i2c->dev->ctr.ms_mode = (slave_addr == 0); i2c->dev->ctr.sda_force_out = 1 ; i2c->dev->ctr.scl_force_out = 1 ; - i2c->dev->ctr.sample_scl_level = 0 ; + i2c->dev->ctr.clk_en = 1; i2c->dev->timeout.tout = 2000; i2c->dev->fifo_conf.nonfifo_en = 0; + i2c->dev->slave_addr.val = 0; if (slave_addr) { i2c->dev->slave_addr.addr = slave_addr; i2c->dev->slave_addr.en_10bit = addr_10bit_en; From 8bfca04afe7da0f7ceddbde4a90e84c2b32f1fec Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 10 Oct 2016 13:53:55 +0300 Subject: [PATCH 11/33] I2C SDA should properly register the ACK bit from some slaves --- cores/esp32/esp32-hal-i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp32/esp32-hal-i2c.c b/cores/esp32/esp32-hal-i2c.c index 71c153c0b4c..83a527c04db 100644 --- a/cores/esp32/esp32-hal-i2c.c +++ b/cores/esp32/esp32-hal-i2c.c @@ -26,7 +26,7 @@ void i2cAttachSCL(i2c_t * i2c, int8_t scl) { - pinMode(scl, INPUT); + pinMode(scl, OUTPUT_OPEN_DRAIN); pinMatrixOutAttach(scl, I2C_SCL_IDX(i2c->num), false, false); pinMatrixInAttach(scl, I2C_SCL_IDX(i2c->num), false); } @@ -40,7 +40,7 @@ void i2cDetachSCL(i2c_t * i2c, int8_t scl) void i2cAttachSDA(i2c_t * i2c, int8_t sda) { - pinMode(sda, INPUT); + pinMode(sda, OUTPUT_OPEN_DRAIN); pinMatrixOutAttach(sda, I2C_SDA_IDX(i2c->num), false, false); pinMatrixInAttach(sda, I2C_SDA_IDX(i2c->num), false); } From a4f360036e7d84b7549a6af2f14638ee359a0800 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 10 Oct 2016 14:10:43 +0300 Subject: [PATCH 12/33] prevent some devices from locking the SCL line --- cores/esp32/esp32-hal-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp32/esp32-hal-i2c.c b/cores/esp32/esp32-hal-i2c.c index 83a527c04db..bb78e71dce5 100644 --- a/cores/esp32/esp32-hal-i2c.c +++ b/cores/esp32/esp32-hal-i2c.c @@ -26,7 +26,7 @@ void i2cAttachSCL(i2c_t * i2c, int8_t scl) { - pinMode(scl, OUTPUT_OPEN_DRAIN); + pinMode(scl, OUTPUT); pinMatrixOutAttach(scl, I2C_SCL_IDX(i2c->num), false, false); pinMatrixInAttach(scl, I2C_SCL_IDX(i2c->num), false); } From df46317b7cf11cec7ef1d1da0d41092e22c4c35f Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 10 Oct 2016 14:54:36 +0300 Subject: [PATCH 13/33] Prevent I2C Bus locks and wrong data being sent on retry --- cores/esp32/esp32-hal-i2c.c | 82 +++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/cores/esp32/esp32-hal-i2c.c b/cores/esp32/esp32-hal-i2c.c index bb78e71dce5..3dcf1a63c20 100644 --- a/cores/esp32/esp32-hal-i2c.c +++ b/cores/esp32/esp32-hal-i2c.c @@ -89,6 +89,8 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin uint8_t willSend = (dataLen > 32)?32:dataLen; uint8_t dataSend = willSend; + i2cResetFiFo(i2c); + //CMD START i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false); @@ -124,33 +126,31 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin //WAIT Transmission while(1) { + //Bus failed (maybe check for this while waiting? + if(i2c->dev->int_raw.arbitration_lost) { + //log_e("Bus Fail! Addr: %x", address >> 1); + return 4; + } + + //Bus timeout + if(i2c->dev->int_raw.time_out) { + //log_e("Bus Timeout! Addr: %x", address >> 1); + return 3; + } + + //Transmission did not finish and ACK_ERR is set + if(i2c->dev->int_raw.ack_err) { + //log_e("Ack Error! Addr: %x", address >> 1); + return 1; + } + if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[2].done)) { continue; - } else if(i2c->dev->int_raw.ack_err || i2c->dev->int_raw.time_out || i2c->dev->int_raw.arbitration_lost) { - break; } else if(i2c->dev->command[2].done) { break; } } - //Bus failed (maybe check for this while waiting? - if(i2c->dev->int_raw.arbitration_lost) { - //log_e("Bus Fail! Addr: %x", address >> 1); - return 4; - } - - //Bus timeout - if(i2c->dev->int_raw.time_out) { - //log_e("Bus Timeout! Addr: %x", address >> 1); - return 3; - } - - //Transmission did not finish and ACK_ERR is set - if(i2c->dev->int_raw.ack_err) { - //log_e("Ack Error! Addr: %x", address >> 1); - return 1; - } - } return 0; } @@ -163,6 +163,8 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint uint8_t cmdIdx; uint8_t willRead; + i2cResetFiFo(i2c); + //CMD START i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false); @@ -176,6 +178,10 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint while(len) { cmdIdx = (index)?0:2; willRead = (len > 32)?32:(len-1); + if(cmdIdx){ + i2cResetFiFo(i2c); + } + i2cSetCmd(i2c, cmdIdx++, I2C_CMD_READ, willRead, false, false, false); if((len - willRead) > 1) { i2cSetCmd(i2c, cmdIdx++, I2C_CMD_END, 0, false, false, false); @@ -195,32 +201,30 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint //WAIT Transmission while(1) { + //Bus failed (maybe check for this while waiting? + if(i2c->dev->int_raw.arbitration_lost) { + //log_e("Bus Fail! Addr: %x", address >> 1); + return -4; + } + + //Bus timeout + if(i2c->dev->int_raw.time_out) { + //log_e("Bus Timeout! Addr: %x", address >> 1); + return -3; + } + + //Transmission did not finish and ACK_ERR is set + if(i2c->dev->int_raw.ack_err) { + //log_e("Ack Error! Addr: %x", address >> 1); + return -1; + } if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[cmdIdx-1].done)) { continue; - } else if(i2c->dev->int_raw.ack_err || i2c->dev->int_raw.time_out || i2c->dev->int_raw.arbitration_lost) { - break; } else if(i2c->dev->command[cmdIdx-1].done) { break; } } - //Bus failed (maybe check for this while waiting? - if(i2c->dev->int_raw.arbitration_lost) { - //log_e("Bus Fail! Addr: %x", address >> 1); - return -4; - } - - //Bus timeout - if(i2c->dev->int_raw.time_out) { - //log_e("Bus Timeout! Addr: %x", address >> 1); - return -3; - } - - //Transmission did not finish and ACK_ERR is set - if(i2c->dev->int_raw.ack_err) { - //log_e("Ack Error! Addr: %x", address >> 1); - return -1; - } int i = 0; while(i Date: Mon, 10 Oct 2016 17:37:34 +0300 Subject: [PATCH 14/33] use local buffer for printf if size is equal or less than 64 --- cores/esp32/Print.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cores/esp32/Print.cpp b/cores/esp32/Print.cpp index 34584c50e43..9f7b35da21c 100644 --- a/cores/esp32/Print.cpp +++ b/cores/esp32/Print.cpp @@ -46,13 +46,16 @@ size_t Print::write(const uint8_t *buffer, size_t size) size_t Print::printf(const char *format, ...) { - char * temp; + char loc_buf[64]; + char * temp = loc_buf; va_list arg; va_start(arg, format); size_t len = vsnprintf(NULL, 0, format, arg); - temp = new char[len+1]; - if(temp == NULL) { - return 0; + if(len > 64){ + temp = new char[len+1]; + if(temp == NULL) { + return 0; + } } len = vsnprintf(temp, len+1, format, arg); write((uint8_t*)temp, len); From 2f512bc531546177af09aad148c186c2afdfb989 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 10 Oct 2016 19:29:25 +0300 Subject: [PATCH 15/33] Do not delete printf buffer if not required --- cores/esp32/Print.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cores/esp32/Print.cpp b/cores/esp32/Print.cpp index 9f7b35da21c..d758478b2a4 100644 --- a/cores/esp32/Print.cpp +++ b/cores/esp32/Print.cpp @@ -60,7 +60,9 @@ size_t Print::printf(const char *format, ...) len = vsnprintf(temp, len+1, format, arg); write((uint8_t*)temp, len); va_end(arg); - delete[] temp; + if(len > 64){ + delete[] temp; + } return len; } /* From ae2a98455b1733f66aee27b1e81ab470da7f8c6b Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 11 Oct 2016 03:59:34 +0300 Subject: [PATCH 16/33] fix Serial RX This trick does not fix GPIO interrupts. Different INUM maybe for GPIO on APP cpu --- cores/esp32/esp32-hal-uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index fc018241a52..d589f04657c 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -90,7 +90,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx pinMode(uart->rxPin, INPUT); pinMatrixInAttach(uart->rxPin, UART_RXD_IDX(uart->num), uart->inverted); - intr_matrix_set(PRO_CPU_NUM, UART_INTR_SOURCE(uart->num), UART_INUM(uart->num)); + intr_matrix_set(APP_CPU_NUM, UART_INTR_SOURCE(uart->num), UART_INUM(uart->num)); xt_set_interrupt_handler(UART_INUM(uart->num), _uart_isr, uart); ESP_INTR_ENABLE(UART_INUM(uart->num)); conf1 = (112 << UART_RXFIFO_FULL_THRHD_S) | (0x02 << UART_RX_TOUT_THRHD_S) | UART_RX_TOUT_EN; From 89a3e09dec6badc06dbb4ef19dd869cdf80771c1 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 11 Oct 2016 11:16:43 +0300 Subject: [PATCH 17/33] attach uart isr on the current core --- cores/esp32/esp32-hal-uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index d589f04657c..2554799191e 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -90,7 +90,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx pinMode(uart->rxPin, INPUT); pinMatrixInAttach(uart->rxPin, UART_RXD_IDX(uart->num), uart->inverted); - intr_matrix_set(APP_CPU_NUM, UART_INTR_SOURCE(uart->num), UART_INUM(uart->num)); + intr_matrix_set(xPortGetCoreID(), UART_INTR_SOURCE(uart->num), UART_INUM(uart->num)); xt_set_interrupt_handler(UART_INUM(uart->num), _uart_isr, uart); ESP_INTR_ENABLE(UART_INUM(uart->num)); conf1 = (112 << UART_RXFIFO_FULL_THRHD_S) | (0x02 << UART_RX_TOUT_THRHD_S) | UART_RX_TOUT_EN; From 9b01daa027746a872cf1507c875abcf79734e713 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 11 Oct 2016 11:42:47 +0300 Subject: [PATCH 18/33] copy va_list in Print::printf --- cores/esp32/Print.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cores/esp32/Print.cpp b/cores/esp32/Print.cpp index d758478b2a4..5afa9dedd42 100644 --- a/cores/esp32/Print.cpp +++ b/cores/esp32/Print.cpp @@ -49,9 +49,12 @@ size_t Print::printf(const char *format, ...) char loc_buf[64]; char * temp = loc_buf; va_list arg; + va_list copy; va_start(arg, format); + va_copy(copy, arg); size_t len = vsnprintf(NULL, 0, format, arg); - if(len > 64){ + va_end(copy); + if(len >= sizeof(loc_buf)){ temp = new char[len+1]; if(temp == NULL) { return 0; From d5a59e16d75dff731b7093a05be9d750e2c883b0 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 11 Oct 2016 12:07:18 +0300 Subject: [PATCH 19/33] fix GPIO attachInterrupt --- cores/esp32/esp32-hal-gpio.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cores/esp32/esp32-hal-gpio.c b/cores/esp32/esp32-hal-gpio.c index 729b56f3627..15e33da7cae 100644 --- a/cores/esp32/esp32-hal-gpio.c +++ b/cores/esp32/esp32-hal-gpio.c @@ -190,13 +190,14 @@ extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type) if(!interrupt_initialized) { interrupt_initialized = true; ESP_INTR_DISABLE(ETS_GPIO_INUM); - intr_matrix_set(PRO_CPU_NUM, ETS_GPIO_INTR_SOURCE, ETS_GPIO_INUM); + intr_matrix_set(xPortGetCoreID(), ETS_GPIO_INTR_SOURCE, ETS_GPIO_INUM); xt_set_interrupt_handler(ETS_GPIO_INUM, &__onPinInterrupt, NULL); ESP_INTR_ENABLE(ETS_GPIO_INUM); } __pinInterruptHandlers[pin] = userFunc; ESP_INTR_DISABLE(ETS_GPIO_INUM); - GPIO.pin[pin].val = (GPIO.pin[pin].val & ~((GPIO_PIN0_INT_ENA << GPIO_PIN0_INT_ENA_S) | (GPIO_PIN0_INT_TYPE << GPIO_PIN0_INT_TYPE_S))) | (((uint32_t)0x4 << GPIO_PIN0_INT_ENA_S) | ((uint32_t)intr_type << GPIO_PIN0_INT_TYPE_S)); + GPIO.pin[pin].int_ena = 1; + GPIO.pin[pin].int_type = intr_type; ESP_INTR_ENABLE(ETS_GPIO_INUM); } @@ -204,7 +205,8 @@ extern void __detachInterrupt(uint8_t pin) { __pinInterruptHandlers[pin] = NULL; ESP_INTR_DISABLE(ETS_GPIO_INUM); - GPIO.pin[pin].val = (GPIO.pin[pin].val & ~((GPIO_PIN0_INT_ENA << GPIO_PIN0_INT_ENA_S) | (GPIO_PIN0_INT_TYPE << GPIO_PIN0_INT_TYPE_S))); + GPIO.pin[pin].int_ena = 0; + GPIO.pin[pin].int_type = 0; ESP_INTR_ENABLE(ETS_GPIO_INUM); } From 74aeafb47532e1d7867825f3b6e59945b17115d1 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 11 Oct 2016 12:29:06 +0300 Subject: [PATCH 20/33] really fix attachInterrupt to work on either core --- cores/esp32/esp32-hal-gpio.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cores/esp32/esp32-hal-gpio.c b/cores/esp32/esp32-hal-gpio.c index 15e33da7cae..e879afab728 100644 --- a/cores/esp32/esp32-hal-gpio.c +++ b/cores/esp32/esp32-hal-gpio.c @@ -187,16 +187,23 @@ static void IRAM_ATTR __onPinInterrupt(void *arg) extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type) { static bool interrupt_initialized = false; + static int core_id = 0; + if(!interrupt_initialized) { interrupt_initialized = true; + core_id = xPortGetCoreID(); ESP_INTR_DISABLE(ETS_GPIO_INUM); - intr_matrix_set(xPortGetCoreID(), ETS_GPIO_INTR_SOURCE, ETS_GPIO_INUM); + intr_matrix_set(core_id, ETS_GPIO_INTR_SOURCE, ETS_GPIO_INUM); xt_set_interrupt_handler(ETS_GPIO_INUM, &__onPinInterrupt, NULL); ESP_INTR_ENABLE(ETS_GPIO_INUM); } __pinInterruptHandlers[pin] = userFunc; ESP_INTR_DISABLE(ETS_GPIO_INUM); - GPIO.pin[pin].int_ena = 1; + if(core_id) { //APP_CPU + GPIO.pin[pin].int_ena = 1; + } else { //PRO_CPU + GPIO.pin[pin].int_ena = 4; + } GPIO.pin[pin].int_type = intr_type; ESP_INTR_ENABLE(ETS_GPIO_INUM); } From 713ff09f22a857eb70aa577b5cf61be62302f2a4 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 11 Oct 2016 14:20:02 +0300 Subject: [PATCH 21/33] implement thread-safe i2c --- cores/esp32/esp32-hal-i2c.c | 120 ++++++++++++++++++++++++++++-------- cores/esp32/esp32-hal-i2c.h | 8 +-- 2 files changed, 96 insertions(+), 32 deletions(-) diff --git a/cores/esp32/esp32-hal-i2c.c b/cores/esp32/esp32-hal-i2c.c index 3dcf1a63c20..8681fa58a03 100644 --- a/cores/esp32/esp32-hal-i2c.c +++ b/cores/esp32/esp32-hal-i2c.c @@ -15,51 +15,85 @@ #include "esp32-hal-i2c.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/semphr.h" #include "rom/ets_sys.h" #include "soc/i2c_reg.h" #include "soc/dport_reg.h" -#define I2C_DEV(i) (volatile i2c_dev_t *)((i)?DR_REG_I2C1_EXT_BASE:DR_REG_I2C_EXT_BASE) -//#define I2C_DEV(i) ((i2c_dev_t *)(REG_I2C_BASE(i))) #define I2C_SCL_IDX(p) ((p==0)?I2CEXT0_SCL_OUT_IDX:((p==1)?I2CEXT1_SCL_OUT_IDX:0)) #define I2C_SDA_IDX(p) ((p==0)?I2CEXT0_SDA_OUT_IDX:((p==1)?I2CEXT1_SDA_OUT_IDX:0)) + +struct i2c_struct_t { + i2c_dev_t * dev; + xSemaphoreHandle lock; + uint8_t num; +}; + +enum { + I2C_CMD_RSTART, + I2C_CMD_WRITE, + I2C_CMD_READ, + I2C_CMD_STOP, + I2C_CMD_END +}; + +#define I2C_MUTEX_LOCK() do {} while (xSemaphoreTake(i2c->lock, portMAX_DELAY) != pdPASS) +#define I2C_MUTEX_UNLOCK() xSemaphoreGive(i2c->lock) + +static i2c_t _i2c_bus_array[2] = { + {(volatile i2c_dev_t *)(DR_REG_I2C_EXT_BASE), NULL, 0}, + {(volatile i2c_dev_t *)(DR_REG_I2C1_EXT_BASE), NULL, 1} +}; + void i2cAttachSCL(i2c_t * i2c, int8_t scl) { + if(i2c == NULL){ + return; + } + I2C_MUTEX_LOCK(); pinMode(scl, OUTPUT); pinMatrixOutAttach(scl, I2C_SCL_IDX(i2c->num), false, false); pinMatrixInAttach(scl, I2C_SCL_IDX(i2c->num), false); + I2C_MUTEX_UNLOCK(); } void i2cDetachSCL(i2c_t * i2c, int8_t scl) { + if(i2c == NULL){ + return; + } + I2C_MUTEX_LOCK(); pinMatrixOutDetach(scl, false, false); pinMatrixInDetach(I2C_SCL_IDX(i2c->num), false, false); pinMode(scl, INPUT); + I2C_MUTEX_UNLOCK(); } void i2cAttachSDA(i2c_t * i2c, int8_t sda) { + if(i2c == NULL){ + return; + } + I2C_MUTEX_LOCK(); pinMode(sda, OUTPUT_OPEN_DRAIN); pinMatrixOutAttach(sda, I2C_SDA_IDX(i2c->num), false, false); pinMatrixInAttach(sda, I2C_SDA_IDX(i2c->num), false); + I2C_MUTEX_UNLOCK(); } void i2cDetachSDA(i2c_t * i2c, int8_t sda) { + if(i2c == NULL){ + return; + } + I2C_MUTEX_LOCK(); pinMatrixOutDetach(sda, false, false); pinMatrixInDetach(I2C_SDA_IDX(i2c->num), false, false); pinMode(sda, INPUT); + I2C_MUTEX_UNLOCK(); } -enum { - I2C_CMD_RSTART, - I2C_CMD_WRITE, - I2C_CMD_READ, - I2C_CMD_STOP, - I2C_CMD_END -}; - /* * index - command index (0 to 15) * op_code - is the command @@ -78,6 +112,14 @@ void i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bo i2c->dev->command[index].op_code = op_code; } +void i2cResetFiFo(i2c_t * i2c) +{ + i2c->dev->fifo_conf.tx_fifo_rst = 1; + i2c->dev->fifo_conf.tx_fifo_rst = 0; + i2c->dev->fifo_conf.rx_fifo_rst = 1; + i2c->dev->fifo_conf.rx_fifo_rst = 0; +} + int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop) { int i; @@ -85,6 +127,12 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin uint8_t dataLen = len + (addr_10bit?2:1); address = (address << 1); + if(i2c == NULL){ + return 4; + } + + I2C_MUTEX_LOCK(); + while(dataLen) { uint8_t willSend = (dataLen > 32)?32:dataLen; uint8_t dataSend = willSend; @@ -129,18 +177,21 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin //Bus failed (maybe check for this while waiting? if(i2c->dev->int_raw.arbitration_lost) { //log_e("Bus Fail! Addr: %x", address >> 1); + I2C_MUTEX_UNLOCK(); return 4; } //Bus timeout if(i2c->dev->int_raw.time_out) { //log_e("Bus Timeout! Addr: %x", address >> 1); + I2C_MUTEX_UNLOCK(); return 3; } //Transmission did not finish and ACK_ERR is set if(i2c->dev->int_raw.ack_err) { //log_e("Ack Error! Addr: %x", address >> 1); + I2C_MUTEX_UNLOCK(); return 1; } @@ -152,6 +203,7 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin } } + I2C_MUTEX_UNLOCK(); return 0; } @@ -163,6 +215,12 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint uint8_t cmdIdx; uint8_t willRead; + if(i2c == NULL){ + return 4; + } + + I2C_MUTEX_LOCK(); + i2cResetFiFo(i2c); //CMD START @@ -204,18 +262,21 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint //Bus failed (maybe check for this while waiting? if(i2c->dev->int_raw.arbitration_lost) { //log_e("Bus Fail! Addr: %x", address >> 1); + I2C_MUTEX_UNLOCK(); return -4; } //Bus timeout if(i2c->dev->int_raw.time_out) { //log_e("Bus Timeout! Addr: %x", address >> 1); + I2C_MUTEX_UNLOCK(); return -3; } //Transmission did not finish and ACK_ERR is set if(i2c->dev->int_raw.ack_err) { //log_e("Ack Error! Addr: %x", address >> 1); + I2C_MUTEX_UNLOCK(); return -1; } if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[cmdIdx-1].done)) { @@ -232,22 +293,19 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint } len -= willRead; } + I2C_MUTEX_UNLOCK(); return 0; } -void i2cResetFiFo(i2c_t * i2c) -{ - //TX FIFO - i2c->dev->fifo_conf.tx_fifo_rst = 1; - i2c->dev->fifo_conf.tx_fifo_rst = 0; - //RX FIFO - i2c->dev->fifo_conf.rx_fifo_rst = 1; - i2c->dev->fifo_conf.rx_fifo_rst = 0; -} - void i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed) { uint32_t period = (APB_CLK_FREQ/clk_speed) / 2; + + if(i2c == NULL){ + return; + } + + I2C_MUTEX_LOCK(); i2c->dev->scl_low_period.scl_low_period = period; i2c->dev->scl_high_period.period = period; @@ -259,10 +317,15 @@ void i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed) i2c->dev->sda_hold.time = 25; i2c->dev->sda_sample.time = 25; + I2C_MUTEX_UNLOCK(); } uint32_t i2cGetFrequency(i2c_t * i2c) { + if(i2c == NULL){ + return 0; + } + return APB_CLK_FREQ/(i2c->dev->scl_low_period.scl_low_period+i2c->dev->scl_high_period.period); } @@ -274,18 +337,23 @@ uint32_t i2cGetFrequency(i2c_t * i2c) i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en) { - i2c_t* i2c = (i2c_t*) malloc(sizeof(i2c_t)); - if(i2c == 0) { + if(i2c_num > 1){ return NULL; } - i2c->num = i2c_num; - i2c->dev = I2C_DEV(i2c_num); + i2c_t * i2c = &_i2c_bus_array[i2c_num]; + + if(i2c->lock == NULL){ + i2c->lock = xSemaphoreCreateMutex(); + if(i2c->lock == NULL) { + return NULL; + } + } - if(i2c->num == 0) { + if(i2c_num == 0) { SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG,DPORT_I2C_EXT0_CLK_EN); CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT0_RST); - } else if(i2c->num == 1) { + } else { SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG,DPORT_I2C_EXT1_CLK_EN); CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT1_RST); } diff --git a/cores/esp32/esp32-hal-i2c.h b/cores/esp32/esp32-hal-i2c.h index d543ee95920..b9987867031 100644 --- a/cores/esp32/esp32-hal-i2c.h +++ b/cores/esp32/esp32-hal-i2c.h @@ -22,18 +22,14 @@ extern "C" { #include "esp32-hal.h" #include "soc/i2c_struct.h" -typedef struct { - i2c_dev_t * dev; - uint8_t num; -} i2c_t; +struct i2c_struct_t; +typedef struct i2c_struct_t i2c_t; i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en); void i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed); uint32_t i2cGetFrequency(i2c_t * i2c); -void i2cResetFiFo(i2c_t * i2c); - void i2cAttachSCL(i2c_t * i2c, int8_t scl); void i2cDetachSCL(i2c_t * i2c, int8_t scl); void i2cAttachSDA(i2c_t * i2c, int8_t sda); From cff7f6986ce780a164c110aa0cf941592cdfb8e4 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 11 Oct 2016 15:11:51 +0300 Subject: [PATCH 22/33] return proper errors --- cores/esp32/esp32-hal-i2c.c | 53 ++++++++++++++++++++++--------------- cores/esp32/esp32-hal-i2c.h | 26 +++++++++++------- 2 files changed, 48 insertions(+), 31 deletions(-) diff --git a/cores/esp32/esp32-hal-i2c.c b/cores/esp32/esp32-hal-i2c.c index 8681fa58a03..baba392f582 100644 --- a/cores/esp32/esp32-hal-i2c.c +++ b/cores/esp32/esp32-hal-i2c.c @@ -13,13 +13,17 @@ // limitations under the License. #include "esp32-hal-i2c.h" +#include "esp32-hal.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "rom/ets_sys.h" #include "soc/i2c_reg.h" +#include "soc/i2c_struct.h" #include "soc/dport_reg.h" +//#define I2C_DEV(i) (volatile i2c_dev_t *)((i)?DR_REG_I2C1_EXT_BASE:DR_REG_I2C_EXT_BASE) +//#define I2C_DEV(i) ((i2c_dev_t *)(REG_I2C_BASE(i))) #define I2C_SCL_IDX(p) ((p==0)?I2CEXT0_SCL_OUT_IDX:((p==1)?I2CEXT1_SCL_OUT_IDX:0)) #define I2C_SDA_IDX(p) ((p==0)?I2CEXT0_SDA_OUT_IDX:((p==1)?I2CEXT1_SDA_OUT_IDX:0)) @@ -46,52 +50,56 @@ static i2c_t _i2c_bus_array[2] = { {(volatile i2c_dev_t *)(DR_REG_I2C1_EXT_BASE), NULL, 1} }; -void i2cAttachSCL(i2c_t * i2c, int8_t scl) +i2c_err_t i2cAttachSCL(i2c_t * i2c, int8_t scl) { if(i2c == NULL){ - return; + return I2C_ERROR_DEV; } I2C_MUTEX_LOCK(); pinMode(scl, OUTPUT); pinMatrixOutAttach(scl, I2C_SCL_IDX(i2c->num), false, false); pinMatrixInAttach(scl, I2C_SCL_IDX(i2c->num), false); I2C_MUTEX_UNLOCK(); + return I2C_ERROR_OK; } -void i2cDetachSCL(i2c_t * i2c, int8_t scl) +i2c_err_t i2cDetachSCL(i2c_t * i2c, int8_t scl) { if(i2c == NULL){ - return; + return I2C_ERROR_DEV; } I2C_MUTEX_LOCK(); pinMatrixOutDetach(scl, false, false); pinMatrixInDetach(I2C_SCL_IDX(i2c->num), false, false); pinMode(scl, INPUT); I2C_MUTEX_UNLOCK(); + return I2C_ERROR_OK; } -void i2cAttachSDA(i2c_t * i2c, int8_t sda) +i2c_err_t i2cAttachSDA(i2c_t * i2c, int8_t sda) { if(i2c == NULL){ - return; + return I2C_ERROR_DEV; } I2C_MUTEX_LOCK(); pinMode(sda, OUTPUT_OPEN_DRAIN); pinMatrixOutAttach(sda, I2C_SDA_IDX(i2c->num), false, false); pinMatrixInAttach(sda, I2C_SDA_IDX(i2c->num), false); I2C_MUTEX_UNLOCK(); + return I2C_ERROR_OK; } -void i2cDetachSDA(i2c_t * i2c, int8_t sda) +i2c_err_t i2cDetachSDA(i2c_t * i2c, int8_t sda) { if(i2c == NULL){ - return; + return I2C_ERROR_DEV; } I2C_MUTEX_LOCK(); pinMatrixOutDetach(sda, false, false); pinMatrixInDetach(I2C_SDA_IDX(i2c->num), false, false); pinMode(sda, INPUT); I2C_MUTEX_UNLOCK(); + return I2C_ERROR_OK; } /* @@ -120,7 +128,7 @@ void i2cResetFiFo(i2c_t * i2c) i2c->dev->fifo_conf.rx_fifo_rst = 0; } -int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop) +i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop) { int i; uint8_t index = 0; @@ -128,7 +136,7 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin address = (address << 1); if(i2c == NULL){ - return 4; + return I2C_ERROR_DEV; } I2C_MUTEX_LOCK(); @@ -178,21 +186,21 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin if(i2c->dev->int_raw.arbitration_lost) { //log_e("Bus Fail! Addr: %x", address >> 1); I2C_MUTEX_UNLOCK(); - return 4; + return I2C_ERROR_BUS; } //Bus timeout if(i2c->dev->int_raw.time_out) { //log_e("Bus Timeout! Addr: %x", address >> 1); I2C_MUTEX_UNLOCK(); - return 3; + return I2C_ERROR_TIMEOUT; } //Transmission did not finish and ACK_ERR is set if(i2c->dev->int_raw.ack_err) { //log_e("Ack Error! Addr: %x", address >> 1); I2C_MUTEX_UNLOCK(); - return 1; + return I2C_ERROR_ACK; } if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[2].done)) { @@ -204,10 +212,10 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin } I2C_MUTEX_UNLOCK(); - return 0; + return I2C_ERROR_OK; } -int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop) +i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop) { address = (address << 1) | 1; uint8_t addrLen = (addr_10bit?2:1); @@ -216,7 +224,7 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint uint8_t willRead; if(i2c == NULL){ - return 4; + return I2C_ERROR_DEV; } I2C_MUTEX_LOCK(); @@ -263,21 +271,21 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint if(i2c->dev->int_raw.arbitration_lost) { //log_e("Bus Fail! Addr: %x", address >> 1); I2C_MUTEX_UNLOCK(); - return -4; + return I2C_ERROR_BUS; } //Bus timeout if(i2c->dev->int_raw.time_out) { //log_e("Bus Timeout! Addr: %x", address >> 1); I2C_MUTEX_UNLOCK(); - return -3; + return I2C_ERROR_TIMEOUT; } //Transmission did not finish and ACK_ERR is set if(i2c->dev->int_raw.ack_err) { //log_e("Ack Error! Addr: %x", address >> 1); I2C_MUTEX_UNLOCK(); - return -1; + return I2C_ERROR_ACK; } if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[cmdIdx-1].done)) { continue; @@ -294,15 +302,15 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint len -= willRead; } I2C_MUTEX_UNLOCK(); - return 0; + return I2C_ERROR_OK; } -void i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed) +i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed) { uint32_t period = (APB_CLK_FREQ/clk_speed) / 2; if(i2c == NULL){ - return; + return I2C_ERROR_DEV; } I2C_MUTEX_LOCK(); @@ -318,6 +326,7 @@ void i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed) i2c->dev->sda_hold.time = 25; i2c->dev->sda_sample.time = 25; I2C_MUTEX_UNLOCK(); + return I2C_ERROR_OK; } uint32_t i2cGetFrequency(i2c_t * i2c) diff --git a/cores/esp32/esp32-hal-i2c.h b/cores/esp32/esp32-hal-i2c.h index b9987867031..bcf3bc7ef5d 100644 --- a/cores/esp32/esp32-hal-i2c.h +++ b/cores/esp32/esp32-hal-i2c.h @@ -19,24 +19,32 @@ extern "C" { #endif -#include "esp32-hal.h" -#include "soc/i2c_struct.h" +#include +#include + +typedef enum { + I2C_ERROR_OK, + I2C_ERROR_DEV, + I2C_ERROR_ACK, + I2C_ERROR_TIMEOUT, + I2C_ERROR_BUS +} i2c_err_t; struct i2c_struct_t; typedef struct i2c_struct_t i2c_t; i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en); -void i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed); +i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed); uint32_t i2cGetFrequency(i2c_t * i2c); -void i2cAttachSCL(i2c_t * i2c, int8_t scl); -void i2cDetachSCL(i2c_t * i2c, int8_t scl); -void i2cAttachSDA(i2c_t * i2c, int8_t sda); -void i2cDetachSDA(i2c_t * i2c, int8_t sda); +i2c_err_t i2cAttachSCL(i2c_t * i2c, int8_t scl); +i2c_err_t i2cDetachSCL(i2c_t * i2c, int8_t scl); +i2c_err_t i2cAttachSDA(i2c_t * i2c, int8_t sda); +i2c_err_t i2cDetachSDA(i2c_t * i2c, int8_t sda); -int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop); -int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop); +i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop); +i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop); #ifdef __cplusplus From 13af2c79ec56d50cedd7244cc7ac39450f25b631 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 11 Oct 2016 15:51:09 +0300 Subject: [PATCH 23/33] implement thread-safe spi --- cores/esp32/esp32-hal-spi.c | 108 ++++++++++++++++++++++++++++++++---- cores/esp32/esp32-hal-spi.h | 10 ++-- 2 files changed, 101 insertions(+), 17 deletions(-) diff --git a/cores/esp32/esp32-hal-spi.c b/cores/esp32/esp32-hal-spi.c index 9e0f0c590a3..f4462d8cd6f 100644 --- a/cores/esp32/esp32-hal-spi.c +++ b/cores/esp32/esp32-hal-spi.c @@ -13,20 +13,20 @@ // limitations under the License. #include "esp32-hal-spi.h" +#include "esp32-hal.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/semphr.h" #include "rom/ets_sys.h" #include "esp_attr.h" #include "esp_intr.h" #include "rom/gpio.h" #include "soc/spi_reg.h" +#include "soc/spi_struct.h" #include "soc/io_mux_reg.h" #include "soc/gpio_sig_map.h" #include "soc/dport_reg.h" -#define SPI_REG_BASE(p) ((p==0)?DR_REG_SPI0_BASE:((p==1)?DR_REG_SPI1_BASE:((p==2)?DR_REG_SPI2_BASE:((p==3)?DR_REG_SPI3_BASE:0)))) -#define SPI_DEV(i) ((spi_dev_t *)(SPI_REG_BASE(i))) - #define SPI_CLK_IDX(p) ((p==0)?SPICLK_OUT_IDX:((p==1)?SPICLK_OUT_IDX:((p==2)?HSPICLK_OUT_IDX:((p==3)?VSPICLK_OUT_MUX_IDX:0)))) #define SPI_MISO_IDX(p) ((p==0)?SPIQ_OUT_IDX:((p==1)?SPIQ_OUT_IDX:((p==2)?HSPIQ_OUT_IDX:((p==3)?VSPIQ_OUT_IDX:0)))) #define SPI_MOSI_IDX(p) ((p==0)?SPID_IN_IDX:((p==1)?SPID_IN_IDX:((p==2)?HSPID_IN_IDX:((p==3)?VSPID_IN_IDX:0)))) @@ -39,6 +39,22 @@ #define SPI_INUM(u) (2) #define SPI_INTR_SOURCE(u) ((u==0)?ETS_SPI0_INTR_SOURCE:((u==1)?ETS_SPI1_INTR_SOURCE:((u==2)?ETS_SPI2_INTR_SOURCE:((p==3)?ETS_SPI3_INTR_SOURCE:0)))) +struct spi_struct_t { + spi_dev_t * dev; + xSemaphoreHandle lock; + uint8_t num; +}; + +#define SPI_MUTEX_LOCK() do {} while (xSemaphoreTake(spi->lock, portMAX_DELAY) != pdPASS) +#define SPI_MUTEX_UNLOCK() xSemaphoreGive(spi->lock) + +static spi_t _spi_bus_array[4] = { + {(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0}, + {(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 1}, + {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 2}, + {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 3} +}; + void spiAttachSCK(spi_t * spi, int8_t sck) { if(!spi) { @@ -53,8 +69,10 @@ void spiAttachSCK(spi_t * spi, int8_t sck) sck = 6; } } + SPI_MUTEX_LOCK(); pinMode(sck, OUTPUT); pinMatrixOutAttach(sck, SPI_CLK_IDX(spi->num), false, false); + SPI_MUTEX_UNLOCK(); } void spiAttachMISO(spi_t * spi, int8_t miso) @@ -71,8 +89,10 @@ void spiAttachMISO(spi_t * spi, int8_t miso) miso = 7; } } + SPI_MUTEX_LOCK(); pinMode(miso, INPUT); pinMatrixInAttach(miso, SPI_MISO_IDX(spi->num), false); + SPI_MUTEX_UNLOCK(); } void spiAttachMOSI(spi_t * spi, int8_t mosi) @@ -89,8 +109,10 @@ void spiAttachMOSI(spi_t * spi, int8_t mosi) mosi = 8; } } + SPI_MUTEX_LOCK(); pinMode(mosi, OUTPUT); pinMatrixOutAttach(mosi, SPI_MOSI_IDX(spi->num), false, false); + SPI_MUTEX_UNLOCK(); } void spiDetachSCK(spi_t * spi, int8_t sck) @@ -107,8 +129,10 @@ void spiDetachSCK(spi_t * spi, int8_t sck) sck = 6; } } + SPI_MUTEX_LOCK(); pinMatrixOutDetach(sck, false, false); pinMode(sck, INPUT); + SPI_MUTEX_UNLOCK(); } void spiDetachMISO(spi_t * spi, int8_t miso) @@ -125,8 +149,10 @@ void spiDetachMISO(spi_t * spi, int8_t miso) miso = 7; } } + SPI_MUTEX_LOCK(); pinMatrixInDetach(SPI_MISO_IDX(spi->num), false, false); pinMode(miso, INPUT); + SPI_MUTEX_UNLOCK(); } void spiDetachMOSI(spi_t * spi, int8_t mosi) @@ -143,8 +169,10 @@ void spiDetachMOSI(spi_t * spi, int8_t mosi) mosi = 8; } } + SPI_MUTEX_LOCK(); pinMatrixOutDetach(mosi, false, false); pinMode(mosi, INPUT); + SPI_MUTEX_UNLOCK(); } void spiAttachSS(spi_t * spi, uint8_t cs_num, int8_t ss) @@ -165,9 +193,11 @@ void spiAttachSS(spi_t * spi, uint8_t cs_num, int8_t ss) ss = 11; } } + SPI_MUTEX_LOCK(); pinMode(ss, OUTPUT); pinMatrixOutAttach(ss, SPI_SS_IDX(spi->num, cs_num), false, false); spiEnableSSPins(spi, (1 << cs_num)); + SPI_MUTEX_UNLOCK(); } void spiDetachSS(spi_t * spi, int8_t ss) @@ -184,8 +214,10 @@ void spiDetachSS(spi_t * spi, int8_t ss) ss = 11; } } + SPI_MUTEX_LOCK(); pinMatrixOutDetach(ss, false, false); pinMode(ss, INPUT); + SPI_MUTEX_UNLOCK(); } void spiEnableSSPins(spi_t * spi, uint8_t cs_mask) @@ -193,7 +225,9 @@ void spiEnableSSPins(spi_t * spi, uint8_t cs_mask) if(!spi) { return; } + SPI_MUTEX_LOCK(); spi->dev->pin.val &= ~(cs_mask & SPI_CS_MASK_ALL); + SPI_MUTEX_UNLOCK(); } void spiDisableSSPins(spi_t * spi, uint8_t cs_mask) @@ -201,7 +235,9 @@ void spiDisableSSPins(spi_t * spi, uint8_t cs_mask) if(!spi) { return; } + SPI_MUTEX_LOCK(); spi->dev->pin.val |= (cs_mask & SPI_CS_MASK_ALL); + SPI_MUTEX_UNLOCK(); } void spiSSEnable(spi_t * spi) @@ -209,8 +245,10 @@ void spiSSEnable(spi_t * spi) if(!spi) { return; } + SPI_MUTEX_LOCK(); spi->dev->user.cs_setup = 1; spi->dev->user.cs_hold = 1; + SPI_MUTEX_UNLOCK(); } void spiSSDisable(spi_t * spi) @@ -218,8 +256,10 @@ void spiSSDisable(spi_t * spi) if(!spi) { return; } + SPI_MUTEX_LOCK(); spi->dev->user.cs_setup = 0; spi->dev->user.cs_hold = 0; + SPI_MUTEX_UNLOCK(); } void spiSSSet(spi_t * spi) @@ -227,7 +267,9 @@ void spiSSSet(spi_t * spi) if(!spi) { return; } + SPI_MUTEX_LOCK(); spi->dev->pin.cs_keep_active = 1; + SPI_MUTEX_UNLOCK(); } void spiSSClear(spi_t * spi) @@ -235,7 +277,9 @@ void spiSSClear(spi_t * spi) if(!spi) { return; } + SPI_MUTEX_LOCK(); spi->dev->pin.cs_keep_active = 0; + SPI_MUTEX_UNLOCK(); } uint32_t spiGetClockDiv(spi_t * spi) @@ -243,7 +287,9 @@ uint32_t spiGetClockDiv(spi_t * spi) if(!spi) { return 0; } + SPI_MUTEX_LOCK(); return spi->dev->clock.val; + SPI_MUTEX_UNLOCK(); } void spiSetClockDiv(spi_t * spi, uint32_t clockDiv) @@ -251,7 +297,9 @@ void spiSetClockDiv(spi_t * spi, uint32_t clockDiv) if(!spi) { return; } + SPI_MUTEX_LOCK(); spi->dev->clock.val = clockDiv; + SPI_MUTEX_UNLOCK(); } uint8_t spiGetDataMode(spi_t * spi) @@ -278,6 +326,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode) if(!spi) { return; } + SPI_MUTEX_LOCK(); switch (dataMode) { case SPI_MODE1: spi->dev->pin.ck_idle_edge = 0; @@ -297,6 +346,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode) spi->dev->user.ck_out_edge = 0; break; } + SPI_MUTEX_UNLOCK(); } uint8_t spiGetBitOrder(spi_t * spi) @@ -312,6 +362,7 @@ void spiSetBitOrder(spi_t * spi, uint8_t bitOrder) if(!spi) { return; } + SPI_MUTEX_LOCK(); if (SPI_MSBFIRST == bitOrder) { spi->dev->ctrl.wr_bit_order = 0; spi->dev->ctrl.rd_bit_order = 0; @@ -319,6 +370,7 @@ void spiSetBitOrder(spi_t * spi, uint8_t bitOrder) spi->dev->ctrl.wr_bit_order = 1; spi->dev->ctrl.rd_bit_order = 1; } + SPI_MUTEX_UNLOCK(); } void spiStopBus(spi_t * spi) @@ -326,6 +378,7 @@ void spiStopBus(spi_t * spi) if(!spi) { return; } + SPI_MUTEX_LOCK(); spi->dev->slave.trans_done = 0; spi->dev->slave.slave_mode = 0; spi->dev->pin.val = 0; @@ -335,18 +388,23 @@ void spiStopBus(spi_t * spi) spi->dev->ctrl1.val = 0; spi->dev->ctrl2.val = 0; spi->dev->clock.val = 0; + SPI_MUTEX_UNLOCK(); } spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t bitOrder) { - - spi_t* spi = (spi_t*) malloc(sizeof(spi_t)); - if(spi == 0) { + if(spi_num > 3){ return NULL; } - spi->num = spi_num; - spi->dev = (spi_dev_t *)SPI_DEV(spi_num); + spi_t * spi = &_spi_bus_array[spi_num]; + + if(spi->lock == NULL){ + spi->lock = xSemaphoreCreateMutex(); + if(spi->lock == NULL) { + return NULL; + } + } if(spi_num == HSPI) { SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN_1); @@ -364,6 +422,7 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_ spiSetBitOrder(spi, bitOrder); spiSetClockDiv(spi, clockDiv); + SPI_MUTEX_LOCK(); spi->dev->user.usr_mosi = 1; spi->dev->user.usr_miso = 1; spi->dev->user.doutdin = 1; @@ -372,6 +431,7 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_ for(i=0; i<16; i++) { spi->dev->data_buf[i] = 0x00000000; } + SPI_MUTEX_UNLOCK(); return spi; } @@ -393,6 +453,7 @@ void spiWrite(spi_t * spi, uint32_t *data, uint8_t len) if(len > 16) { len = 16; } + SPI_MUTEX_LOCK(); while(spi->dev->cmd.usr); spi->dev->mosi_dlen.usr_mosi_dbitlen = (len * 32) - 1; spi->dev->miso_dlen.usr_miso_dbitlen = (len * 32) - 1; @@ -400,6 +461,7 @@ void spiWrite(spi_t * spi, uint32_t *data, uint8_t len) spi->dev->data_buf[i] = data[i]; } spi->dev->cmd.usr = 1; + SPI_MUTEX_UNLOCK(); } void spiRead(spi_t * spi, uint32_t *data, uint8_t len) @@ -411,10 +473,12 @@ void spiRead(spi_t * spi, uint32_t *data, uint8_t len) if(len > 16) { len = 16; } + SPI_MUTEX_LOCK(); while(spi->dev->cmd.usr); for(i=0; idev->data_buf[i]; } + SPI_MUTEX_UNLOCK(); } void spiWriteByte(spi_t * spi, uint8_t data) @@ -422,11 +486,13 @@ void spiWriteByte(spi_t * spi, uint8_t data) if(!spi) { return; } + SPI_MUTEX_LOCK(); while(spi->dev->cmd.usr); spi->dev->mosi_dlen.usr_mosi_dbitlen = 7; spi->dev->miso_dlen.usr_miso_dbitlen = 7; spi->dev->data_buf[0] = data; spi->dev->cmd.usr = 1; + SPI_MUTEX_UNLOCK(); } uint8_t spiReadByte(spi_t * spi) @@ -434,8 +500,12 @@ uint8_t spiReadByte(spi_t * spi) if(!spi) { return 0; } + uint8_t data; + SPI_MUTEX_LOCK(); while(spi->dev->cmd.usr); - return spi->dev->data_buf[0] & 0xFF; + data = spi->dev->data_buf[0] & 0xFF; + SPI_MUTEX_UNLOCK(); + return data; } uint32_t __spiTranslate16(uint16_t data, bool msb) @@ -480,11 +550,13 @@ void spiWriteWord(spi_t * spi, uint16_t data) if(!spi) { return; } + SPI_MUTEX_LOCK(); while(spi->dev->cmd.usr); spi->dev->mosi_dlen.usr_mosi_dbitlen = 15; spi->dev->miso_dlen.usr_miso_dbitlen = 15; spi->dev->data_buf[0] = __spiTranslate16(data, !spi->dev->ctrl.wr_bit_order); spi->dev->cmd.usr = 1; + SPI_MUTEX_UNLOCK(); } uint16_t spiReadWord(spi_t * spi) @@ -492,8 +564,12 @@ uint16_t spiReadWord(spi_t * spi) if(!spi) { return 0; } + uint16_t data; + SPI_MUTEX_LOCK(); while(spi->dev->cmd.usr); - return __spiTranslate16(spi->dev->data_buf[0] & 0xFFFF, !spi->dev->ctrl.rd_bit_order); + data = __spiTranslate16(spi->dev->data_buf[0] & 0xFFFF, !spi->dev->ctrl.rd_bit_order); + SPI_MUTEX_UNLOCK(); + return data; } void spiWriteLong(spi_t * spi, uint32_t data) @@ -501,11 +577,13 @@ void spiWriteLong(spi_t * spi, uint32_t data) if(!spi) { return; } + SPI_MUTEX_LOCK(); while(spi->dev->cmd.usr); spi->dev->mosi_dlen.usr_mosi_dbitlen = 31; spi->dev->miso_dlen.usr_miso_dbitlen = 31; spi->dev->data_buf[0] = __spiTranslate32(data, !spi->dev->ctrl.wr_bit_order); spi->dev->cmd.usr = 1; + SPI_MUTEX_UNLOCK(); } uint32_t spiReadLong(spi_t * spi) @@ -513,8 +591,12 @@ uint32_t spiReadLong(spi_t * spi) if(!spi) { return 0; } + uint32_t data; + SPI_MUTEX_LOCK(); while(spi->dev->cmd.usr); - return __spiTranslate32(spi->dev->data_buf[0], !spi->dev->ctrl.rd_bit_order); + data = __spiTranslate32(spi->dev->data_buf[0], !spi->dev->ctrl.rd_bit_order); + SPI_MUTEX_UNLOCK(); + return data; } void spiTransferBits(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits) @@ -529,6 +611,7 @@ void spiTransferBits(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits) uint32_t bytes = (bits + 7) / 8;//64 max uint32_t mask = (((uint64_t)1 << bits) - 1) & 0xFFFFFFFF; + SPI_MUTEX_LOCK(); while(spi->dev->cmd.usr); spi->dev->mosi_dlen.usr_mosi_dbitlen = (bits - 1); spi->dev->miso_dlen.usr_miso_dbitlen = (bits - 1); @@ -555,6 +638,7 @@ void spiTransferBits(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits) *out = __spiTranslate32(spi->dev->data_buf[0] & mask, !spi->dev->ctrl.wr_bit_order); } } + SPI_MUTEX_UNLOCK(); } void __spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t bytes) @@ -605,6 +689,7 @@ void spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t size) if(!spi) { return; } + SPI_MUTEX_LOCK(); while(size) { if(size > 64) { __spiTransferBytes(spi, data, out, 64); @@ -620,6 +705,7 @@ void spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t size) size = 0; } } + SPI_MUTEX_UNLOCK(); } diff --git a/cores/esp32/esp32-hal-spi.h b/cores/esp32/esp32-hal-spi.h index 1ff5e82258b..7766a256658 100644 --- a/cores/esp32/esp32-hal-spi.h +++ b/cores/esp32/esp32-hal-spi.h @@ -19,8 +19,8 @@ extern "C" { #endif -#include "esp32-hal.h" -#include "soc/spi_struct.h" +#include +#include #define SPI_HAS_TRANSACTION @@ -51,10 +51,8 @@ extern "C" { #define SPI_LSBFIRST 0 #define SPI_MSBFIRST 1 -typedef struct { - spi_dev_t * dev; - uint8_t num; -} spi_t; +struct spi_struct_t; +typedef struct spi_struct_t spi_t; spi_t * spiStartBus(uint8_t spi_num, uint32_t freq, uint8_t dataMode, uint8_t bitOrder); void spiStopBus(spi_t * spi); From 9d5881a297ba485596e408bd761afee4d7c7bfbc Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 14 Oct 2016 03:02:40 +0300 Subject: [PATCH 24/33] UART rework many possible problems fixed in preparation for thread-safe --- cores/esp32/HardwareSerial.cpp | 40 +----- cores/esp32/HardwareSerial.h | 2 - cores/esp32/esp32-hal-uart.c | 221 +++++++++++++++++++++------------ cores/esp32/esp32-hal-uart.h | 22 ++-- 4 files changed, 153 insertions(+), 132 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index 423c512abf7..c198b74d7c7 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -33,11 +33,7 @@ void HardwareSerial::setDebugOutput(bool en) return; } if(en) { - if(_uart->txEnabled) { - uartSetDebug(_uart); - } else { - uartSetDebug(0); - } + uartSetDebug(_uart); } else { if(uartGetDebug() == _uart_nr) { uartSetDebug(0); @@ -45,33 +41,14 @@ void HardwareSerial::setDebugOutput(bool en) } } -bool HardwareSerial::isTxEnabled(void) -{ - if(_uart == 0) { - return false; - } - return _uart->txEnabled; -} - -bool HardwareSerial::isRxEnabled(void) -{ - if(_uart == 0) { - return false; - } - return _uart->rxEnabled; -} - int HardwareSerial::available(void) { - if (_uart && _uart->rxEnabled) { - return uartAvailable(_uart); - } - return 0; + return uartAvailable(_uart); } int HardwareSerial::peek(void) { - if (_uart && _uart->rxEnabled) { + if (available()) { return uartPeek(_uart); } return -1; @@ -79,7 +56,7 @@ int HardwareSerial::peek(void) int HardwareSerial::read(void) { - if(_uart && _uart->rxEnabled) { + if(available()) { return uartRead(_uart); } return -1; @@ -87,26 +64,17 @@ int HardwareSerial::read(void) void HardwareSerial::flush() { - if(_uart == 0 || !_uart->txEnabled) { - return; - } uartFlush(_uart); } size_t HardwareSerial::write(uint8_t c) { - if(_uart == 0 || !_uart->txEnabled) { - return 0; - } uartWrite(_uart, c); return 1; } size_t HardwareSerial::write(const uint8_t *buffer, size_t size) { - if(_uart == 0 || !_uart->txEnabled) { - return 0; - } uartWriteBuf(_uart, buffer, size); return size; } diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index 924b1408b83..122b910c2d2 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -65,8 +65,6 @@ class HardwareSerial: public Stream operator bool() const; void setDebugOutput(bool); - bool isTxEnabled(void); - bool isRxEnabled(void); protected: int _uart_nr; diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 2554799191e..589c840fca5 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -13,18 +13,22 @@ // limitations under the License. #include "esp32-hal-uart.h" +#include "esp32-hal.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/queue.h" #include "freertos/semphr.h" #include "rom/ets_sys.h" #include "esp_attr.h" #include "esp_intr.h" #include "rom/uart.h" #include "soc/uart_reg.h" +#include "soc/uart_struct.h" #include "soc/io_mux_reg.h" #include "soc/gpio_sig_map.h" -#define ETS_UART2_INUM 5 +#define ETS_UART_INUM 5 +#define ETS_UART2_INUM ETS_UART_INUM #define UART_REG_BASE(u) ((u==0)?DR_REG_UART_BASE:( (u==1)?DR_REG_UART1_BASE:( (u==2)?DR_REG_UART2_BASE:0))) #define UART_RXD_IDX(u) ((u==0)?U0RXD_IN_IDX:( (u==1)?U1RXD_IN_IDX:( (u==2)?U2RXD_IN_IDX:0))) @@ -34,17 +38,34 @@ static int s_uart_debug_nr = 0; +struct uart_struct_t { + uart_dev_t * dev; + uint8_t num; + xQueueHandle queue; +}; + +static uart_t _uart_bus_array[3] = { + {(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL}, + {(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL}, + {(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL} +}; + static void IRAM_ATTR _uart_isr(void *arg) { - uint8_t c; + uint8_t i, c; BaseType_t xHigherPriorityTaskWoken; - uart_t* uart = (uart_t*)arg; - - uart->dev->int_clr.val = UART_RXFIFO_FULL_INT_ENA | UART_FRM_ERR_INT_ENA | UART_RXFIFO_TOUT_INT_ENA; //Acknowledge the interrupt - while(uart->dev->status.rxfifo_cnt) { - c = uart->dev->fifo.rw_byte; - if(!xQueueIsQueueFullFromISR(uart->queue)) { - xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); + uart_t* uart; + + for(i=0;i<3;i++){ + uart = &_uart_bus_array[i]; + uart->dev->int_clr.rxfifo_full = 1; + uart->dev->int_clr.frm_err = 1; + uart->dev->int_clr.rxfifo_tout = 1; + while(uart->dev->status.rxfifo_cnt) { + c = uart->dev->fifo.rw_byte; + if(uart->queue != NULL && !xQueueIsQueueFullFromISR(uart->queue)) { + xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); + } } } @@ -53,99 +74,138 @@ static void IRAM_ATTR _uart_isr(void *arg) } } -uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted) +void uartEnableGlobalInterrupt() { - uint32_t conf1 = 0; + xt_set_interrupt_handler(ETS_UART_INUM, _uart_isr, NULL); + ESP_INTR_ENABLE(ETS_UART_INUM); +} - if(uart_nr > 2) { - return NULL; +void uartDisableGlobalInterrupt() +{ + ESP_INTR_DISABLE(ETS_UART_INUM); + xt_set_interrupt_handler(ETS_UART_INUM, NULL, NULL); +} + +void uartEnableInterrupt(uart_t* uart) +{ + uart->dev->conf1.rxfifo_full_thrhd = 112; + uart->dev->conf1.rx_tout_thrhd = 2; + uart->dev->conf1.rx_tout_en = 1; + uart->dev->int_ena.rxfifo_full = 1; + uart->dev->int_ena.frm_err = 1; + uart->dev->int_ena.rxfifo_tout = 1; + uart->dev->int_clr.val = 0xffffffff; + + intr_matrix_set(xPortGetCoreID(), UART_INTR_SOURCE(uart->num), ETS_UART_INUM); +} + +void uartDisableInterrupt(uart_t* uart) +{ + uart->dev->conf1.val = 0; + uart->dev->int_ena.val = 0; + uart->dev->int_clr.val = 0xffffffff; +} + +void uartDetachRx(uart_t* uart) +{ + if(uart == NULL) { + return; } + pinMatrixInDetach(UART_RXD_IDX(uart->num), false, false); + uartDisableInterrupt(uart); +} - if(rxPin == -1 && txPin == -1) { - return NULL; +void uartDetachTx(uart_t* uart) +{ + if(uart == NULL) { + return; } + pinMatrixOutDetach(UART_TXD_IDX(uart->num), false, false); +} - uart_t* uart = (uart_t*) malloc(sizeof(uart_t)); - if(uart == 0) { - return NULL; +void uartAttachRx(uart_t* uart, uint8_t rxPin, bool inverted) +{ + if(uart == NULL || rxPin > 39) { + return; } + pinMode(rxPin, INPUT); + pinMatrixInAttach(rxPin, UART_RXD_IDX(uart->num), inverted); + uartEnableInterrupt(uart); + uartEnableGlobalInterrupt(); +} - uart->dev = (uart_dev_t *)UART_REG_BASE(uart_nr); - uart->num = uart_nr; - uart->inverted = inverted; +void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted) +{ + if(uart == NULL || txPin > 39) { + return; + } + pinMode(txPin, OUTPUT); + pinMatrixOutAttach(txPin, UART_TXD_IDX(uart->num), inverted, false); +} - uart->rxPin = rxPin; - uart->txPin = txPin; - uart->rxEnabled = (uart->rxPin != -1); - uart->txEnabled = (uart->txPin != -1); +uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted) +{ + if(uart_nr > 2) { + return NULL; + } - uartFlush(uart); + if(rxPin == -1 && txPin == -1) { + return NULL; + } - if(uart->rxEnabled) { + uart_t* uart = &_uart_bus_array[uart_nr]; + + if(queueLen && uart->queue == NULL) { uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue if(uart->queue == NULL) { - free(uart); return NULL; } - - pinMode(uart->rxPin, INPUT); - pinMatrixInAttach(uart->rxPin, UART_RXD_IDX(uart->num), uart->inverted); - intr_matrix_set(xPortGetCoreID(), UART_INTR_SOURCE(uart->num), UART_INUM(uart->num)); - xt_set_interrupt_handler(UART_INUM(uart->num), _uart_isr, uart); - ESP_INTR_ENABLE(UART_INUM(uart->num)); - conf1 = (112 << UART_RXFIFO_FULL_THRHD_S) | (0x02 << UART_RX_TOUT_THRHD_S) | UART_RX_TOUT_EN; - uart->dev->int_ena.val = UART_RXFIFO_FULL_INT_ENA | UART_FRM_ERR_INT_ENA | UART_RXFIFO_TOUT_INT_ENA; - uart->dev->int_clr.val = 0xffff; - } - if(uart->txEnabled) { - pinMode(uart->txPin, OUTPUT); - pinMatrixOutAttach(uart->txPin, UART_TXD_IDX(uart->num), uart->inverted, false); } + uartFlush(uart); uartSetBaudRate(uart, baudrate); uart->dev->conf0.val = config; - uart->dev->conf1.val = conf1; + + if(rxPin != -1) { + uartAttachRx(uart, rxPin, inverted); + } + + if(txPin != -1) { + uartAttachTx(uart, txPin, inverted); + } + return uart; } void uartEnd(uart_t* uart) { - if(uart == 0) { + if(uart == NULL) { return; } - if(uart->rxEnabled) { - pinMode(uart->rxPin, INPUT); - if(uart->num || uart->rxPin != 3) { - pinMatrixInDetach(UART_RXD_IDX(uart->num), uart->inverted, false); - } - - ESP_INTR_DISABLE(UART_INUM(uart->num)); - xt_set_interrupt_handler(UART_INUM(uart->num), NULL, NULL); + if(uart->queue != NULL) { vQueueDelete(uart->queue); } - if(uart->txEnabled) { - pinMode(uart->txPin, INPUT); - if(uart->num || uart->txPin != 1) { - pinMatrixInDetach(UART_TXD_IDX(uart->num), !uart->inverted, uart->inverted); - } - } - uart->dev->conf0.val = 0; - uart->dev->conf1.val = 0; - uart->dev->int_ena.val = 0; - uart->dev->int_clr.val = 0xffff; + uartDetachRx(uart); + uartDetachTx(uart); - free(uart); + uart->dev->conf0.val = 0; } uint32_t uartAvailable(uart_t* uart) { + if(uart == NULL || uart->queue == NULL) { + return 0; + } return uxQueueMessagesWaiting(uart->queue); } uint8_t uartRead(uart_t* uart) { + if(uart == NULL || uart->queue == NULL) { + return 0; + } uint8_t c; if(xQueueReceive(uart->queue, &c, 0)) { return c; @@ -155,6 +215,9 @@ uint8_t uartRead(uart_t* uart) uint8_t uartPeek(uart_t* uart) { + if(uart == NULL || uart->queue == NULL) { + return 0; + } uint8_t c; if(xQueuePeek(uart->queue, &c, 0)) { return c; @@ -164,14 +227,20 @@ uint8_t uartPeek(uart_t* uart) void uartWrite(uart_t* uart, uint8_t c) { + if(uart == NULL) { + return; + } while(uart->dev->status.rxfifo_cnt == 0x7F); uart->dev->fifo.rw_byte = c; } void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len) { + if(uart == NULL) { + return; + } while(len) { - while(len && uart->dev->status.txfifo_cnt < 0x7F) { + while(len && uart->dev->status.rxfifo_cnt < 0x7F) { uart->dev->fifo.rw_byte = *data++; len--; } @@ -180,31 +249,24 @@ void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len) void uartFlush(uart_t* uart) { - uint32_t tmp = 0x00000000; - - if(uart == 0) { + if(uart == NULL) { return; } - if(uart->rxEnabled) { - tmp |= UART_RXFIFO_RST; - } + while(uart->dev->status.txfifo_cnt); - if(uart->txEnabled) { - while(uart->dev->status.txfifo_cnt); - tmp |= UART_TXFIFO_RST; - } + uart->dev->conf0.txfifo_rst = 1; + uart->dev->conf0.txfifo_rst = 0; - uart->dev->conf0.val |= (tmp); - uart->dev->conf0.val &= ~(tmp); + uart->dev->conf0.rxfifo_rst = 1; + uart->dev->conf0.rxfifo_rst = 0; } void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) { - if(uart == 0) { + if(uart == NULL) { return; } - uart->baud_rate = baud_rate; uint32_t clk_div = ((UART_CLK_FREQ<<4)/baud_rate); uart->dev->clk_div.div_int = clk_div>>4 ; uart->dev->clk_div.div_frag = clk_div & 0xf; @@ -212,10 +274,11 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) uint32_t uartGetBaudRate(uart_t* uart) { - if(uart == 0) { + if(uart == NULL) { return 0; } - return uart->baud_rate; + uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F); + return ((UART_CLK_FREQ<<4)/clk_div); } static void IRAM_ATTR uart0_write_char(char c) diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h index d3669f833ac..ce83f1461c7 100644 --- a/cores/esp32/esp32-hal-uart.h +++ b/cores/esp32/esp32-hal-uart.h @@ -19,10 +19,9 @@ extern "C" { #endif -#include "esp32-hal.h" -#include "soc/uart_struct.h" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" +#include +#include +#include #define SERIAL_5N1 0x8000010 #define SERIAL_6N1 0x8000014 @@ -49,17 +48,8 @@ extern "C" { #define SERIAL_7O2 0x800003b #define SERIAL_8O2 0x800003f -typedef struct { - uart_dev_t * dev; - xQueueHandle queue; - uint32_t baud_rate; - uint8_t num; - int8_t rxPin; - int8_t txPin; - bool rxEnabled; - bool txEnabled; - bool inverted; -} uart_t; +struct uart_struct_t; +typedef struct uart_struct_t uart_t; uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted); void uartEnd(uart_t* uart); @@ -67,8 +57,10 @@ void uartEnd(uart_t* uart); uint32_t uartAvailable(uart_t* uart); uint8_t uartRead(uart_t* uart); uint8_t uartPeek(uart_t* uart); + void uartWrite(uart_t* uart, uint8_t c); void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len); + void uartFlush(uart_t* uart); void uartSetBaudRate(uart_t* uart, uint32_t baud_rate); From 5cd933e52da43a98e056967073564c64666a5cd9 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 14 Oct 2016 03:07:21 +0300 Subject: [PATCH 25/33] Implement thread-safe uart --- cores/esp32/esp32-hal-uart.c | 44 ++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 589c840fca5..f602d246053 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -40,14 +40,21 @@ static int s_uart_debug_nr = 0; struct uart_struct_t { uart_dev_t * dev; + xSemaphoreHandle lock; uint8_t num; xQueueHandle queue; }; +#define UART_MUTEX_LOCK() do {} while (xSemaphoreTake(uart->lock, portMAX_DELAY) != pdPASS) +#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock) + +#define UART_MUTEX_LOCK_NUM(i) if(_uart_bus_array[i].lock != NULL) do {} while (xSemaphoreTake(_uart_bus_array[i].lock, portMAX_DELAY) != pdPASS) +#define UART_MUTEX_UNLOCK_NUM(i) if(_uart_bus_array[i].lock != NULL) xSemaphoreGive(_uart_bus_array[i].lock) + static uart_t _uart_bus_array[3] = { - {(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL} + {(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL}, + {(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL}, + {(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL} }; static void IRAM_ATTR _uart_isr(void *arg) @@ -88,6 +95,7 @@ void uartDisableGlobalInterrupt() void uartEnableInterrupt(uart_t* uart) { + UART_MUTEX_LOCK(); uart->dev->conf1.rxfifo_full_thrhd = 112; uart->dev->conf1.rx_tout_thrhd = 2; uart->dev->conf1.rx_tout_en = 1; @@ -97,13 +105,16 @@ void uartEnableInterrupt(uart_t* uart) uart->dev->int_clr.val = 0xffffffff; intr_matrix_set(xPortGetCoreID(), UART_INTR_SOURCE(uart->num), ETS_UART_INUM); + UART_MUTEX_UNLOCK(); } void uartDisableInterrupt(uart_t* uart) { + UART_MUTEX_LOCK(); uart->dev->conf1.val = 0; uart->dev->int_ena.val = 0; uart->dev->int_clr.val = 0xffffffff; + UART_MUTEX_UNLOCK(); } void uartDetachRx(uart_t* uart) @@ -154,7 +165,14 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx } uart_t* uart = &_uart_bus_array[uart_nr]; - + + if(uart->lock == NULL) { + uart->lock = xSemaphoreCreateMutex(); + if(uart->lock == NULL) { + return NULL; + } + } + if(queueLen && uart->queue == NULL) { uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue if(uart->queue == NULL) { @@ -164,7 +182,9 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx uartFlush(uart); uartSetBaudRate(uart, baudrate); + UART_MUTEX_LOCK(); uart->dev->conf0.val = config; + UART_MUTEX_UNLOCK(); if(rxPin != -1) { uartAttachRx(uart, rxPin, inverted); @@ -183,6 +203,7 @@ void uartEnd(uart_t* uart) return; } + UART_MUTEX_LOCK(); if(uart->queue != NULL) { vQueueDelete(uart->queue); } @@ -191,6 +212,7 @@ void uartEnd(uart_t* uart) uartDetachTx(uart); uart->dev->conf0.val = 0; + UART_MUTEX_UNLOCK(); } uint32_t uartAvailable(uart_t* uart) @@ -230,8 +252,10 @@ void uartWrite(uart_t* uart, uint8_t c) if(uart == NULL) { return; } + UART_MUTEX_LOCK(); while(uart->dev->status.rxfifo_cnt == 0x7F); uart->dev->fifo.rw_byte = c; + UART_MUTEX_UNLOCK(); } void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len) @@ -239,12 +263,14 @@ void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len) if(uart == NULL) { return; } + UART_MUTEX_LOCK(); while(len) { while(len && uart->dev->status.rxfifo_cnt < 0x7F) { uart->dev->fifo.rw_byte = *data++; len--; } } + UART_MUTEX_UNLOCK(); } void uartFlush(uart_t* uart) @@ -253,6 +279,7 @@ void uartFlush(uart_t* uart) return; } + UART_MUTEX_LOCK(); while(uart->dev->status.txfifo_cnt); uart->dev->conf0.txfifo_rst = 1; @@ -260,6 +287,7 @@ void uartFlush(uart_t* uart) uart->dev->conf0.rxfifo_rst = 1; uart->dev->conf0.rxfifo_rst = 0; + UART_MUTEX_UNLOCK(); } void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) @@ -267,9 +295,11 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) if(uart == NULL) { return; } + UART_MUTEX_LOCK(); uint32_t clk_div = ((UART_CLK_FREQ<<4)/baud_rate); uart->dev->clk_div.div_int = clk_div>>4 ; uart->dev->clk_div.div_frag = clk_div & 0xf; + UART_MUTEX_UNLOCK(); } uint32_t uartGetBaudRate(uart_t* uart) @@ -283,20 +313,26 @@ uint32_t uartGetBaudRate(uart_t* uart) static void IRAM_ATTR uart0_write_char(char c) { + UART_MUTEX_LOCK_NUM(0); while(((ESP_REG(0x01C+DR_REG_UART_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); ESP_REG(DR_REG_UART_BASE) = c; + UART_MUTEX_UNLOCK_NUM(0); } static void IRAM_ATTR uart1_write_char(char c) { + UART_MUTEX_LOCK_NUM(1); while(((ESP_REG(0x01C+DR_REG_UART1_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); ESP_REG(DR_REG_UART1_BASE) = c; + UART_MUTEX_UNLOCK_NUM(1); } static void IRAM_ATTR uart2_write_char(char c) { + UART_MUTEX_LOCK_NUM(2); while(((ESP_REG(0x01C+DR_REG_UART2_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); ESP_REG(DR_REG_UART2_BASE) = c; + UART_MUTEX_UNLOCK_NUM(2); } void uartSetDebug(uart_t* uart) From c36a891ea18249c7e15c0d56d255b1b90dfe4d54 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 14 Oct 2016 03:16:02 +0300 Subject: [PATCH 26/33] remove unnecessary locks --- cores/esp32/esp32-hal-spi.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/cores/esp32/esp32-hal-spi.c b/cores/esp32/esp32-hal-spi.c index f4462d8cd6f..7947108c150 100644 --- a/cores/esp32/esp32-hal-spi.c +++ b/cores/esp32/esp32-hal-spi.c @@ -69,10 +69,8 @@ void spiAttachSCK(spi_t * spi, int8_t sck) sck = 6; } } - SPI_MUTEX_LOCK(); pinMode(sck, OUTPUT); pinMatrixOutAttach(sck, SPI_CLK_IDX(spi->num), false, false); - SPI_MUTEX_UNLOCK(); } void spiAttachMISO(spi_t * spi, int8_t miso) @@ -109,10 +107,8 @@ void spiAttachMOSI(spi_t * spi, int8_t mosi) mosi = 8; } } - SPI_MUTEX_LOCK(); pinMode(mosi, OUTPUT); pinMatrixOutAttach(mosi, SPI_MOSI_IDX(spi->num), false, false); - SPI_MUTEX_UNLOCK(); } void spiDetachSCK(spi_t * spi, int8_t sck) @@ -129,10 +125,8 @@ void spiDetachSCK(spi_t * spi, int8_t sck) sck = 6; } } - SPI_MUTEX_LOCK(); pinMatrixOutDetach(sck, false, false); pinMode(sck, INPUT); - SPI_MUTEX_UNLOCK(); } void spiDetachMISO(spi_t * spi, int8_t miso) @@ -149,10 +143,8 @@ void spiDetachMISO(spi_t * spi, int8_t miso) miso = 7; } } - SPI_MUTEX_LOCK(); pinMatrixInDetach(SPI_MISO_IDX(spi->num), false, false); pinMode(miso, INPUT); - SPI_MUTEX_UNLOCK(); } void spiDetachMOSI(spi_t * spi, int8_t mosi) @@ -169,10 +161,8 @@ void spiDetachMOSI(spi_t * spi, int8_t mosi) mosi = 8; } } - SPI_MUTEX_LOCK(); pinMatrixOutDetach(mosi, false, false); pinMode(mosi, INPUT); - SPI_MUTEX_UNLOCK(); } void spiAttachSS(spi_t * spi, uint8_t cs_num, int8_t ss) @@ -193,11 +183,9 @@ void spiAttachSS(spi_t * spi, uint8_t cs_num, int8_t ss) ss = 11; } } - SPI_MUTEX_LOCK(); pinMode(ss, OUTPUT); pinMatrixOutAttach(ss, SPI_SS_IDX(spi->num, cs_num), false, false); spiEnableSSPins(spi, (1 << cs_num)); - SPI_MUTEX_UNLOCK(); } void spiDetachSS(spi_t * spi, int8_t ss) @@ -214,10 +202,8 @@ void spiDetachSS(spi_t * spi, int8_t ss) ss = 11; } } - SPI_MUTEX_LOCK(); pinMatrixOutDetach(ss, false, false); pinMode(ss, INPUT); - SPI_MUTEX_UNLOCK(); } void spiEnableSSPins(spi_t * spi, uint8_t cs_mask) @@ -287,9 +273,7 @@ uint32_t spiGetClockDiv(spi_t * spi) if(!spi) { return 0; } - SPI_MUTEX_LOCK(); return spi->dev->clock.val; - SPI_MUTEX_UNLOCK(); } void spiSetClockDiv(spi_t * spi, uint32_t clockDiv) From c4cd31da9c812532e71909b6fc82539cc6e51443 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 14 Oct 2016 03:24:20 +0300 Subject: [PATCH 27/33] remove unnecessary locks --- cores/esp32/esp32-hal-i2c.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/cores/esp32/esp32-hal-i2c.c b/cores/esp32/esp32-hal-i2c.c index baba392f582..d845bc098fd 100644 --- a/cores/esp32/esp32-hal-i2c.c +++ b/cores/esp32/esp32-hal-i2c.c @@ -55,11 +55,9 @@ i2c_err_t i2cAttachSCL(i2c_t * i2c, int8_t scl) if(i2c == NULL){ return I2C_ERROR_DEV; } - I2C_MUTEX_LOCK(); pinMode(scl, OUTPUT); pinMatrixOutAttach(scl, I2C_SCL_IDX(i2c->num), false, false); pinMatrixInAttach(scl, I2C_SCL_IDX(i2c->num), false); - I2C_MUTEX_UNLOCK(); return I2C_ERROR_OK; } @@ -68,11 +66,9 @@ i2c_err_t i2cDetachSCL(i2c_t * i2c, int8_t scl) if(i2c == NULL){ return I2C_ERROR_DEV; } - I2C_MUTEX_LOCK(); pinMatrixOutDetach(scl, false, false); pinMatrixInDetach(I2C_SCL_IDX(i2c->num), false, false); pinMode(scl, INPUT); - I2C_MUTEX_UNLOCK(); return I2C_ERROR_OK; } @@ -81,11 +77,9 @@ i2c_err_t i2cAttachSDA(i2c_t * i2c, int8_t sda) if(i2c == NULL){ return I2C_ERROR_DEV; } - I2C_MUTEX_LOCK(); pinMode(sda, OUTPUT_OPEN_DRAIN); pinMatrixOutAttach(sda, I2C_SDA_IDX(i2c->num), false, false); pinMatrixInAttach(sda, I2C_SDA_IDX(i2c->num), false); - I2C_MUTEX_UNLOCK(); return I2C_ERROR_OK; } @@ -94,11 +88,9 @@ i2c_err_t i2cDetachSDA(i2c_t * i2c, int8_t sda) if(i2c == NULL){ return I2C_ERROR_DEV; } - I2C_MUTEX_LOCK(); pinMatrixOutDetach(sda, false, false); pinMatrixInDetach(I2C_SDA_IDX(i2c->num), false, false); pinMode(sda, INPUT); - I2C_MUTEX_UNLOCK(); return I2C_ERROR_OK; } @@ -366,7 +358,8 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en) SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG,DPORT_I2C_EXT1_CLK_EN); CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT1_RST); } - + + I2C_MUTEX_LOCK(); i2c->dev->ctr.val = 0; i2c->dev->ctr.ms_mode = (slave_addr == 0); i2c->dev->ctr.sda_force_out = 1 ; @@ -381,6 +374,7 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en) i2c->dev->slave_addr.addr = slave_addr; i2c->dev->slave_addr.en_10bit = addr_10bit_en; } + I2C_MUTEX_UNLOCK(); return i2c; } From a2e3506e41ad10fb4da093250b12816378674825 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 17 Oct 2016 15:31:51 +0300 Subject: [PATCH 28/33] fix reported data size and percentage --- boards.txt | 2 +- platform.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/boards.txt b/boards.txt index e1433716bd0..bedeb240702 100644 --- a/boards.txt +++ b/boards.txt @@ -6,7 +6,7 @@ esp32.name=ESP32 Dev Module esp32.upload.tool=esptool esp32.upload.maximum_size=1044464 -esp32.upload.maximum_data_size=114688 +esp32.upload.maximum_data_size=294912 esp32.upload.wait_for_upload_port=true esp32.serial.disableDTR=true diff --git a/platform.txt b/platform.txt index 96415179108..ac4d7be8e64 100644 --- a/platform.txt +++ b/platform.txt @@ -81,7 +81,7 @@ recipe.output.save_file={build.project_name}.{build.variant}.bin ## Compute size recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" recipe.size.regex=^(?:\.iram0\.text|\.dram0\.text|\.flash\.text|\.dram0\.data|\.flash\.rodata|)\s+([0-9]+).* -recipe.size.regex.data=^(?:\.dram0\.data|\.flash\.rodata|\.dram0\.bss)\s+([0-9]+).* +recipe.size.regex.data=^(?:\.dram0\.data|\.dram0\.bss)\s+([0-9]+).* # ------------------------------ From 74197b19ad0e6cae2775654b7bcba6cb2b97a8ed Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 17 Oct 2016 15:34:55 +0300 Subject: [PATCH 29/33] do not lock for ets_printf --- cores/esp32/esp32-hal-uart.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index f602d246053..bfee8c5e795 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -48,9 +48,6 @@ struct uart_struct_t { #define UART_MUTEX_LOCK() do {} while (xSemaphoreTake(uart->lock, portMAX_DELAY) != pdPASS) #define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock) -#define UART_MUTEX_LOCK_NUM(i) if(_uart_bus_array[i].lock != NULL) do {} while (xSemaphoreTake(_uart_bus_array[i].lock, portMAX_DELAY) != pdPASS) -#define UART_MUTEX_UNLOCK_NUM(i) if(_uart_bus_array[i].lock != NULL) xSemaphoreGive(_uart_bus_array[i].lock) - static uart_t _uart_bus_array[3] = { {(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL}, {(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL}, @@ -313,26 +310,20 @@ uint32_t uartGetBaudRate(uart_t* uart) static void IRAM_ATTR uart0_write_char(char c) { - UART_MUTEX_LOCK_NUM(0); while(((ESP_REG(0x01C+DR_REG_UART_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); ESP_REG(DR_REG_UART_BASE) = c; - UART_MUTEX_UNLOCK_NUM(0); } static void IRAM_ATTR uart1_write_char(char c) { - UART_MUTEX_LOCK_NUM(1); while(((ESP_REG(0x01C+DR_REG_UART1_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); ESP_REG(DR_REG_UART1_BASE) = c; - UART_MUTEX_UNLOCK_NUM(1); } static void IRAM_ATTR uart2_write_char(char c) { - UART_MUTEX_LOCK_NUM(2); while(((ESP_REG(0x01C+DR_REG_UART2_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); ESP_REG(DR_REG_UART2_BASE) = c; - UART_MUTEX_UNLOCK_NUM(2); } void uartSetDebug(uart_t* uart) From f0c99efb0579e89bd619dca49ef1eac542ddfcb8 Mon Sep 17 00:00:00 2001 From: Tisham Dhar Date: Mon, 17 Oct 2016 12:20:15 +1030 Subject: [PATCH 30/33] Ignore certificates on windows Added code to bypass certificate verification. merge with caution. --- tools/get.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/get.py b/tools/get.py index 80bcb227eb9..dcce8fa346a 100755 --- a/tools/get.py +++ b/tools/get.py @@ -70,9 +70,12 @@ def get_tool(tool): local_path = dist_dir + archive_name url = tool['url'] #real_hash = tool['checksum'].split(':')[1] + ctx = ssl.create_default_context() + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE if not os.path.isfile(local_path): print('Downloading ' + archive_name); - urlretrieve(url, local_path, report_progress) + urlretrieve(url, local_path, report_progress,context=ctx) sys.stdout.write("\rDone\n") sys.stdout.flush() else: From b366e843a1604bc8afbef1b147f21231ef2bceee Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 17 Oct 2016 17:08:57 +0300 Subject: [PATCH 31/33] ignore ssl only on windows --- tools/get.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/get.py b/tools/get.py index dcce8fa346a..aa6d669cdbf 100755 --- a/tools/get.py +++ b/tools/get.py @@ -66,16 +66,21 @@ def unpack(filename, destination): shutil.move(dirname, rename_to) def get_tool(tool): + sys_name = platform.system() archive_name = tool['archiveFileName'] local_path = dist_dir + archive_name url = tool['url'] #real_hash = tool['checksum'].split(':')[1] - ctx = ssl.create_default_context() - ctx.check_hostname = False - ctx.verify_mode = ssl.CERT_NONE + if 'CYGWIN_NT' in sys_name: + ctx = ssl.create_default_context() + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE if not os.path.isfile(local_path): print('Downloading ' + archive_name); - urlretrieve(url, local_path, report_progress,context=ctx) + if 'CYGWIN_NT' in sys_name: + urlretrieve(url, local_path, report_progress,context=ctx) + else: + urlretrieve(url, local_path, report_progress) sys.stdout.write("\rDone\n") sys.stdout.flush() else: From 5f1a818666e445817a531f5311fbe9c45bf1263a Mon Sep 17 00:00:00 2001 From: Electronic Sweet Peas Date: Mon, 17 Oct 2016 16:53:13 +0200 Subject: [PATCH 32/33] First addition of ESP320 support (#19) * First addition of ESP320 support * Updated maximum data size. --- boards.txt | 41 ++++++++++++++++++++++++++++++++++ variants/esp320/pins_arduino.h | 33 +++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 variants/esp320/pins_arduino.h diff --git a/boards.txt b/boards.txt index bedeb240702..d604a73295b 100644 --- a/boards.txt +++ b/boards.txt @@ -41,6 +41,7 @@ esp32.menu.UploadSpeed.460800.upload.speed=460800 esp32.menu.UploadSpeed.512000.windows=512000 esp32.menu.UploadSpeed.512000.upload.speed=512000 +<<<<<<< b366e843a1604bc8afbef1b147f21231ef2bceee ############################################################## nano32.name=Nano32 @@ -81,3 +82,43 @@ nano32.menu.UploadSpeed.460800.macosx=460800 nano32.menu.UploadSpeed.460800.upload.speed=460800 nano32.menu.UploadSpeed.512000.windows=512000 nano32.menu.UploadSpeed.512000.upload.speed=512000 + +############################################################## +esp320.name=Electronic SweetPeas - ESP320 + +esp320.upload.tool=esptool +esp320.upload.maximum_size=1044464 +esp320.upload.maximum_data_size=294912 +esp320.upload.wait_for_upload_port=true + +esp320.serial.disableDTR=true +esp320.serial.disableRTS=true + +esp320.build.mcu=esp32 +esp320.build.core=esp32 +esp320.build.variant=esp320 +esp320.build.board=ESP320 + +esp320.build.f_cpu=160000000L +esp320.build.flash_mode=qio +esp320.build.flash_size=4MB + +esp320.menu.FlashFreq.80=80MHz +esp320.menu.FlashFreq.80.build.flash_freq=80m +esp320.menu.FlashFreq.40=40MHz +esp320.menu.FlashFreq.40.build.flash_freq=40m + +esp320.menu.UploadSpeed.921600=921600 +esp320.menu.UploadSpeed.921600.upload.speed=921600 +esp320.menu.UploadSpeed.115200=115200 +esp320.menu.UploadSpeed.115200.upload.speed=115200 +esp320.menu.UploadSpeed.256000.windows=256000 +esp320.menu.UploadSpeed.256000.upload.speed=256000 +esp320.menu.UploadSpeed.230400.windows.upload.speed=256000 +esp320.menu.UploadSpeed.230400=230400 +esp320.menu.UploadSpeed.230400.upload.speed=230400 +esp320.menu.UploadSpeed.460800.linux=460800 +esp320.menu.UploadSpeed.460800.macosx=460800 +esp320.menu.UploadSpeed.460800.upload.speed=460800 +esp320.menu.UploadSpeed.512000.windows=512000 +esp320.menu.UploadSpeed.512000.upload.speed=512000 diff --git a/variants/esp320/pins_arduino.h b/variants/esp320/pins_arduino.h new file mode 100644 index 00000000000..ee7663657ab --- /dev/null +++ b/variants/esp320/pins_arduino.h @@ -0,0 +1,33 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + + +#define digitalPinToPort(pin) (0) +#define digitalPinToBitMask(pin) (1UL << (pin)) +#define digitalPinToTimer(pin) (0) +#define portOutputRegister(port) +#define portInputRegister(port) +#define portModeRegister(port) + +#define NOT_A_PIN -1 +#define NOT_A_PORT -1 +#define NOT_AN_INTERRUPT -1 +#define NOT_ON_TIMER 0 + +#define EXTERNAL_NUM_INTERRUPTS 11 +#define NUM_DIGITAL_PINS 12 +#define NUM_ANALOG_INPUTS 5 + +#define analogInputToDigitalPin(p) +#define digitalPinToInterrupt(p) +#define digitalPinHasPWM(p) + +static const uint8_t SDA = 2; +static const uint8_t SCL = 14; + +static const uint8_t SS = 15; +static const uint8_t MOSI = 13; +static const uint8_t MISO = 12; +static const uint8_t SCK = 14; + +#endif /* Pins_Arduino_h */ From 6bfaa525169d347c0370ed4566a7807ce1912e87 Mon Sep 17 00:00:00 2001 From: Nat Date: Fri, 7 Oct 2016 13:10:13 +0700 Subject: [PATCH 33/33] Add Nano32 --- boards.txt | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/boards.txt b/boards.txt index d604a73295b..0feae01b507 100644 --- a/boards.txt +++ b/boards.txt @@ -122,3 +122,43 @@ esp320.menu.UploadSpeed.460800.macosx=460800 esp320.menu.UploadSpeed.460800.upload.speed=460800 esp320.menu.UploadSpeed.512000.windows=512000 esp320.menu.UploadSpeed.512000.upload.speed=512000 + +############################################################## +nano32.name=Nano32 + +nano32.upload.tool=esptool +nano32.upload.maximum_size=1044464 +nano32.upload.maximum_data_size=114688 +nano32.upload.wait_for_upload_port=true + +nano32.serial.disableDTR=true +nano32.serial.disableRTS=true + +nano32.build.mcu=esp32 +nano32.build.core=esp32 +nano32.build.variant=nano32 +nano32.build.board=NANO32 + +nano32.build.f_cpu=160000000L +nano32.build.flash_mode=dio +nano32.build.flash_size=4MB + +nano32.menu.FlashFreq.80=80MHz +nano32.menu.FlashFreq.80.build.flash_freq=80m +nano32.menu.FlashFreq.40=40MHz +nano32.menu.FlashFreq.40.build.flash_freq=40m + +nano32.menu.UploadSpeed.921600=921600 +nano32.menu.UploadSpeed.921600.upload.speed=921600 +nano32.menu.UploadSpeed.115200=115200 +nano32.menu.UploadSpeed.115200.upload.speed=115200 +nano32.menu.UploadSpeed.256000.windows=256000 +nano32.menu.UploadSpeed.256000.upload.speed=256000 +nano32.menu.UploadSpeed.230400.windows.upload.speed=256000 +nano32.menu.UploadSpeed.230400=230400 +nano32.menu.UploadSpeed.230400.upload.speed=230400 +nano32.menu.UploadSpeed.460800.linux=460800 +nano32.menu.UploadSpeed.460800.macosx=460800 +nano32.menu.UploadSpeed.460800.upload.speed=460800 +nano32.menu.UploadSpeed.512000.windows=512000 +nano32.menu.UploadSpeed.512000.upload.speed=512000