1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-25 20:02:37 +03:00

Merge pull request #23 from Links2004/esp8266

pull markus's changes
This commit is contained in:
ficeto 2015-05-17 16:45:32 +03:00
commit 93c456602c
12 changed files with 365 additions and 32 deletions

View File

@ -42,12 +42,12 @@ extern "C" {
#define UART_TX_FIFO_SIZE 0x80
struct uart_ {
int uart_nr;
int uart_nr;
int baud_rate;
bool rxEnabled;
bool txEnabled;
uint8_t rxPin;
uint8_t txPin;
uint8_t rxPin;
uint8_t txPin;
};
static const int UART0 = 0;
@ -120,7 +120,7 @@ void ICACHE_RAM_ATTR uart_interrupt_handler(uart_t* uart) {
// -------------- UART 0 --------------
if(Serial.isRxEnabled()) {
while(U0IS & (1 << UIFF)) {
Serial._rx_complete_irq((char)(U0F & 0xff));
Serial._rx_complete_irq((char) (U0F & 0xff));
U0IC = (1 << UIFF);
}
}
@ -135,7 +135,7 @@ void ICACHE_RAM_ATTR uart_interrupt_handler(uart_t* uart) {
if(Serial1.isRxEnabled()) {
while(U1IS & (1 << UIFF)) {
Serial1._rx_complete_irq((char)(U1F & 0xff));
Serial1._rx_complete_irq((char) (U1F & 0xff));
U1IC = (1 << UIFF);
}
}
@ -357,19 +357,19 @@ void uart_swap(uart_t* uart) {
switch(uart->uart_nr) {
case UART0:
if(uart->txPin == 1 && uart->rxPin == 3) {
pinMode(15, FUNCTION_4);//TX
pinMode(13, FUNCTION_4);//RX
pinMode(15, FUNCTION_4); //TX
pinMode(13, FUNCTION_4); //RX
USWAP |= (1 << USWAP0);
pinMode(1, INPUT);//TX
pinMode(3, INPUT);//RX
pinMode(1, INPUT); //TX
pinMode(3, INPUT); //RX
uart->rxPin = 13;
uart->txPin = 15;
} else {
pinMode(1, SPECIAL);//TX
pinMode(3, SPECIAL);//RX
pinMode(1, SPECIAL); //TX
pinMode(3, SPECIAL); //RX
USWAP &= ~(1 << USWAP0);
pinMode(15, INPUT);//TX
pinMode(13, INPUT);//RX
pinMode(15, INPUT); //TX
pinMode(13, INPUT); //RX
uart->rxPin = 3;
uart->txPin = 1;
}
@ -400,6 +400,14 @@ void uart0_write_char(char c) {
return;
}
}
// wait for the Hardware FIFO
while(true) {
if(((USS(0) >> USTXC) & 0xff) <= (UART_TX_FIFO_SIZE - 2)) {
break;
}
}
if(c == '\n') {
USF(0) = '\r';
}
@ -416,6 +424,14 @@ void uart1_write_char(char c) {
return;
}
}
// wait for the Hardware FIFO
while(true) {
if(((USS(1) >> USTXC) & 0xff) <= (UART_TX_FIFO_SIZE - 2)) {
break;
}
}
if(c == '\n') {
USF(1) = '\r';
}
@ -469,11 +485,11 @@ void HardwareSerial::begin(unsigned long baud, byte config) {
}
if(_uart->rxEnabled) {
if (!_rx_buffer)
if(!_rx_buffer)
_rx_buffer = new cbuf(SERIAL_RX_BUFFER_SIZE);
}
if(_uart->txEnabled) {
if (!_tx_buffer)
if(!_tx_buffer)
_tx_buffer = new cbuf(SERIAL_TX_BUFFER_SIZE);
}
_written = false;

View File

@ -26,10 +26,12 @@ extern "C" {
}
void *operator new(size_t size) {
size = ((size + 3) & ~((size_t)0x3));
return os_malloc(size);
}
void *operator new[](size_t size) {
size = ((size + 3) & ~((size_t)0x3));
return os_malloc(size);
}

View File

@ -38,6 +38,7 @@
#include "user_interface.h"
void* malloc(size_t size) {
size = ((size + 3) & ~((size_t)0x3));
return os_malloc(size);
}
@ -46,6 +47,7 @@ void free(void* ptr) {
}
void* realloc(void* ptr, size_t size) {
size = ((size + 3) & ~((size_t)0x3));
return os_realloc(ptr, size);
}

38
doc/exception_causes.md Normal file
View File

@ -0,0 +1,38 @@
Exception Causes (EXCCAUSE)
===========================================
| EXC-CAUSE Code | Cause Name | Cause Description | Required Option | EXC-VADDR Loaded |
|:--------------:|:---------------------------|:------------------------------------------------------------------------------------------------------------|:-------------------------|:----------------:|
| 0 | IllegalInstructionCause | Illegal instruction | Exception | No |
| 1 | SyscallCause | SYSCALL instruction | Exception | No |
| 2 | InstructionFetchErrorCause | Processor internal physical address or data error during instruction fetch | Exception | Yes |
| 3 | LoadStoreErrorCause | Processor internal physical address or data error during load or store | Exception | Yes |
| 4 | Level1InterruptCause | Level-1 interrupt as indicated by set level-1 bits in the INTERRUPT register | Interrupt | No |
| 5 | AllocaCause | MOVSP instruction, if callers registers are not in the register file | Windowed Register | No |
| 6 | IntegerDivideByZeroCause | QUOS, QUOU, REMS, or REMU divisor operand is zero | 32-bit Integer Divide | No |
| 7 | Reserved for Tensilica | | | |
| 8 | PrivilegedCause | Attempt to execute a privileged operation when CRING ? 0 | MMU | No |
| 9 | LoadStoreAlignmentCause | Load or store to an unaligned address | Unaligned Exception | Yes |
| 10..11 | Reserved for Tensilica | | | |
| 12 | InstrPIFDataErrorCause | PIF data error during instruction fetch | Processor Interface | Yes |
| 13 | LoadStorePIFDataErrorCause | Synchronous PIF data error during LoadStore access | Processor Interface | Yes |
| 14 | InstrPIFAddrErrorCause | PIF address error during instruction fetch | Processor Interface | Yes |
| 15 | LoadStorePIFAddrErrorCause | Synchronous PIF address error during LoadStore access | Processor Interface | Yes |
| 16 | InstTLBMissCause | Error during Instruction TLB refill | MMU | Yes |
| 17 | InstTLBMultiHitCause | Multiple instruction TLB entries matched | MMU | Yes |
| 18 | InstFetchPrivilegeCause | An instruction fetch referenced a virtual address at a ring level less than CRING | MMU | Yes |
| 19 | Reserved for Tensilica | | | |
| 20 | InstFetchProhibitedCause | An instruction fetch referenced a page mapped with an attribute that does not permit instruction fetch | Region Protection or MMU | Yes |
| 21..23 | Reserved for Tensilica | | | |
| 24 | LoadStoreTLBMissCause | Error during TLB refill for a load or store | MMU | Yes |
| 25 | LoadStoreTLBMultiHitCause | Multiple TLB entries matched for a load or store | MMU | Yes |
| 26 | LoadStorePrivilegeCause | A load or store referenced a virtual address at a ring level less than CRING | MMU | Yes |
| 27 | Reserved for Tensilica | | | |
| 28 | LoadProhibitedCause | A load referenced a page mapped with an attribute that does not permit loads | Region Protection or MMU | Yes |
| 29 | StoreProhibitedCause | A store referenced a page mapped with an attribute that does not permit stores | Region Protection or MMU | Yes |
| 30..31 | Reserved for Tensilica | | | |
| 32..39 | CoprocessornDisabled | Coprocessor n instruction when cpn disabled. n varies 0..7 as the cause varies 32..39 | Coprocessor | No |
| 40..63 | Reserved | | | |
Infos from Xtensa Instruction Set Architecture (ISA) Reference Manual

View File

@ -42,7 +42,7 @@ EEPROMClass::EEPROMClass()
void EEPROMClass::begin(size_t size)
{
if (size < 0)
if (size <= 0)
return;
if (size > SPI_FLASH_SEC_SIZE)
size = SPI_FLASH_SEC_SIZE;
@ -50,7 +50,9 @@ void EEPROMClass::begin(size_t size)
_data = new uint8_t[size];
_size = size;
noInterrupts();
spi_flash_read(CONFIG_ADDR, reinterpret_cast<uint32_t*>(_data), _size);
interrupts();
}
void EEPROMClass::end()
@ -59,8 +61,9 @@ void EEPROMClass::end()
return;
commit();
delete[] _data;
if(_data) {
delete[] _data;
}
_data = 0;
_size = 0;
}
@ -70,6 +73,8 @@ uint8_t EEPROMClass::read(int address)
{
if (address < 0 || (size_t)address >= _size)
return 0;
if(!_data)
return 0;
return _data[address];
}
@ -78,6 +83,8 @@ void EEPROMClass::write(int address, uint8_t value)
{
if (address < 0 || (size_t)address >= _size)
return;
if(!_data)
return;
_data[address] = value;
_dirty = true;
@ -90,20 +97,24 @@ bool EEPROMClass::commit()
return false;
if(!_dirty)
return true;
if(!_data)
return false;
ETS_UART_INTR_DISABLE();
noInterrupts();
if(spi_flash_erase_sector(CONFIG_SECTOR) == SPI_FLASH_RESULT_OK) {
if(spi_flash_write(CONFIG_ADDR, reinterpret_cast<uint32_t*>(_data), _size) == SPI_FLASH_RESULT_OK) {
_dirty = false;
ret = true;
}
}
ETS_UART_INTR_ENABLE();
interrupts();
return ret;
}
uint8_t * EEPROMClass::getDataPtr()
{
_dirty = true;
return &_data[0];
}

View File

@ -0,0 +1,33 @@
/*
* This sketch trys to Connect to the best AP based on a given list
*
*/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti WiFiMulti = ESP8266WiFiMulti();
void setup() {
Serial.begin(115200);
delay(10);
WiFiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1");
WiFiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2");
WiFiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");
Serial.println("Connecting Wifi...");
if(wifiMulti.run() == WL_CONNECTED) {
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
}
void loop() {
if(wifiMulti.run() != WL_CONNECTED) {
Serial.println("WiFi not connected!");
delay(1000);
}
}

View File

@ -344,7 +344,7 @@ uint8_t ESP8266WiFiClass::encryptionType(uint8_t i)
return -1;
}
uint8_t ESP8266WiFiClass::status()
wl_status_t ESP8266WiFiClass::status()
{
int status = wifi_station_get_connect_status();

View File

@ -199,7 +199,7 @@ public:
*
* return: one of the value defined in wl_status_t
*/
uint8_t status();
wl_status_t status();
/*
* Resolve the given hostname to an IP address.

View File

@ -0,0 +1,171 @@
/**
*
* @file ESP8266WiFiMulti.cpp
* @date 16.05.2015
* @author Markus Sattler
*
* Copyright (c) 2015 Markus Sattler. All rights reserved.
* This file is part of the esp8266 core 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 "ESP8266WiFiMulti.h"
#include <limits.h>
ESP8266WiFiMulti::ESP8266WiFiMulti() {
}
ESP8266WiFiMulti::~ESP8266WiFiMulti() {
APlistClean();
}
bool ESP8266WiFiMulti::addAP(const char* ssid, const char *passphrase) {
return APlistAdd(ssid, passphrase);
}
wl_status_t ESP8266WiFiMulti::run(void) {
wl_status_t status = WiFi.status();
if(status == WL_DISCONNECTED || status == WL_NO_SSID_AVAIL || status == WL_IDLE_STATUS || status == WL_CONNECT_FAILED) {
WifiAPlist_t bestNetwork { NULL, NULL };
int bestNetworkDb = INT_MIN;
// WiFi.scanNetworks will return the number of networks found
int8_t n = WiFi.scanNetworks();
DEBUG_WIFI_MULTI("[WIFI] scan done\n");
delay(0);
if(n <= 0) {
DEBUG_WIFI_MULTI("[WIFI] no networks found\n");
} else {
DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", n);
for(int8_t i = 0; i < n; ++i) {
const char * ssid_scan = WiFi.SSID(i);
int32_t rssi_scan = WiFi.RSSI(i);
uint8_t sec_scan = WiFi.encryptionType(i);
bool known = false;
for(uint32_t x = 0; x < APlist.size(); x++) {
WifiAPlist_t entry = APlist[x];
if(strcmp(entry.ssid, ssid_scan) == 0) { // SSID match
known = true;
if(rssi_scan > bestNetworkDb) { // best network
if(sec_scan == ENC_TYPE_NONE || entry.passphrase) { // check for passphrase if not open wlan
bestNetworkDb = rssi_scan;
memcpy((void*) &bestNetwork, (void*) &entry, sizeof(bestNetwork));
}
}
break;
}
}
if(known) {
DEBUG_WIFI_MULTI(" ---> ");
} else {
DEBUG_WIFI_MULTI(" ");
}
DEBUG_WIFI_MULTI(" %d: %s (%d) %c\n", i, ssid_scan, rssi_scan, (sec_scan == ENC_TYPE_NONE) ? ' ' : '*');
delay(0);
}
}
DEBUG_WIFI_MULTI("\n\n");
delay(0);
if(bestNetwork.ssid) {
DEBUG_WIFI_MULTI("[WIFI] Connecting SSID: %s (%d)\n", bestNetwork.ssid, bestNetworkDb);
WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase);
status = WiFi.status();
// wait for connection or fail
while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED) {
delay(10);
status = WiFi.status();
}
IPAddress ip;
switch(status) {
case WL_CONNECTED:
ip = WiFi.localIP();
DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n");
DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID());
DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
break;
case WL_NO_SSID_AVAIL:
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild AP not found.\n");
break;
case WL_CONNECT_FAILED:
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild.\n");
break;
default:
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild (%d).\n", status);
break;
}
} else {
DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n");
}
}
return status;
}
// ##################################################################################
bool ESP8266WiFiMulti::APlistAdd(const char* ssid, const char *passphrase) {
WifiAPlist_t newAP;
newAP.ssid = (char*) malloc(strlen(ssid));
if(!newAP.ssid) {
return false;
}
strcpy(newAP.ssid, ssid);
if(passphrase && *passphrase != 0x00) {
newAP.passphrase = (char*) malloc(strlen(passphrase));
}
if(!newAP.passphrase) {
free(newAP.ssid);
return false;
}
strcpy(newAP.passphrase, passphrase);
APlist.push_back(newAP);
return true;
}
void ESP8266WiFiMulti::APlistClean(void) {
for(uint32_t i = 0; i < APlist.size(); i++) {
WifiAPlist_t entry = APlist[i];
if(entry.ssid) {
free(entry.ssid);
}
if(entry.passphrase) {
free(entry.passphrase);
}
}
APlist.clear();
}

View File

@ -0,0 +1,60 @@
/**
*
* @file ESP8266WiFiMulti.h
* @date 16.05.2015
* @author Markus Sattler
*
* Copyright (c) 2015 Markus Sattler. All rights reserved.
* This file is part of the esp8266 core 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
*
*/
#ifndef WIFICLIENTMULTI_H_
#define WIFICLIENTMULTI_H_
#include "ESP8266WiFi.h"
#include <vector>
//#define DEBUG_WIFI_MULTI(...) os_printf( __VA_ARGS__ )
#ifndef DEBUG_WIFI_MULTI
#define DEBUG_WIFI_MULTI(...)
#endif
typedef struct {
char * ssid;
char * passphrase;
} WifiAPlist_t;
class ESP8266WiFiMulti {
public:
ESP8266WiFiMulti();
~ESP8266WiFiMulti();
bool addAP(const char* ssid, const char *passphrase = NULL);
wl_status_t run(void);
private:
std::vector<WifiAPlist_t> APlist;
bool APlistAdd(const char* ssid, const char *passphrase = NULL);
void APlistClean(void);
};
#endif /* WIFICLIENTMULTI_H_ */

View File

@ -48,14 +48,14 @@
#define WL_MAX_ATTEMPT_CONNECTION 10
typedef enum {
WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library
WL_IDLE_STATUS = 0,
WL_NO_SSID_AVAIL,
WL_SCAN_COMPLETED,
WL_CONNECTED,
WL_CONNECT_FAILED,
WL_CONNECTION_LOST,
WL_DISCONNECTED
WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library
WL_IDLE_STATUS = 0,
WL_NO_SSID_AVAIL = 1,
WL_SCAN_COMPLETED = 2,
WL_CONNECTED = 3,
WL_CONNECT_FAILED = 4,
WL_CONNECTION_LOST = 5,
WL_DISCONNECTED = 6
} wl_status_t;
/* Encryption modes */

View File

@ -15,7 +15,7 @@ compiler.sdk.path={compiler.tools.path}sdk/
compiler.cpreprocessor.flags=-D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-I{compiler.sdk.path}/include"
compiler.c.cmd=xtensa-lx106-elf-gcc
compiler.c.flags=-c -Os -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -MMD -std=c99
compiler.c.flags=-c -Os -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -falign-functions=4 -MMD -std=c99
compiler.S.cmd=xtensa-lx106-elf-gcc
compiler.S.flags=-c -g -x assembler-with-cpp -MMD
@ -25,7 +25,7 @@ compiler.c.elf.cmd=xtensa-lx106-elf-gcc
compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig
compiler.cpp.cmd=xtensa-lx106-elf-g++
compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -std=c++11 -MMD
compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11 -MMD
compiler.as.cmd=xtensa-lx106-elf-as