mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
Commit of ESP8266 board specific source files.
This commit is contained in:
parent
32a66b2a1c
commit
4eeb12d292
949
libs/network/esp8266/jswrap_esp8266.c
Normal file
949
libs/network/esp8266/jswrap_esp8266.c
Normal file
@ -0,0 +1,949 @@
|
||||
#include <c_types.h>
|
||||
#include <user_interface.h>
|
||||
#include <mem.h>
|
||||
#include <osapi.h>
|
||||
#include <ping.h>
|
||||
#include <espconn.h>
|
||||
#include <espmissingincludes.h>
|
||||
#include <driver/uart.h>
|
||||
|
||||
#define ESP8266_ON_ACCESS_POINTS "#accessPoints"
|
||||
|
||||
#define _GCC_WRAP_STDINT_H
|
||||
typedef long long int64_t;
|
||||
|
||||
#include "jswrap_esp8266.h"
|
||||
#include "jsinteractive.h" // Pull inn the jsiConsolePrint function
|
||||
#include "network.h"
|
||||
#include "network_esp8266.h"
|
||||
#include "jswrap_net.h"
|
||||
|
||||
// Forward declaration of functions.
|
||||
static void scanCB(void *arg, STATUS status);
|
||||
static void wifiEventHandler(System_Event_t *event);
|
||||
static void ipAddrToString(struct ip_addr addr, char *string);
|
||||
static char *nullTerminateString(char *target, char *source, int sourceLength);
|
||||
static void setupJsNetwork();
|
||||
static void pingRecvCB();
|
||||
|
||||
static JsVar *jsScanCallback;
|
||||
static JsVar *jsWiFiEventCallback;
|
||||
|
||||
// A callback function to be invoked when we have an IP address.
|
||||
static JsVar *jsGotIpCallback;
|
||||
|
||||
static JsVar *jsPingCallback;
|
||||
|
||||
// Global data structure for ping request
|
||||
static struct ping_option pingOpt;
|
||||
|
||||
// Let's define the JavaScript class that will contain our `world()` method. We'll call it `Hello`
|
||||
/*JSON{
|
||||
"type" : "class",
|
||||
"class" : "ESP8266WiFi"
|
||||
}*/
|
||||
|
||||
|
||||
/**
|
||||
* \brief Connect the station to an access point.
|
||||
* - `ssid` - The network id of the access point.
|
||||
* - `password` - The password to use to connect to the access point.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "connect",
|
||||
"generate" : "jswrap_ESP8266WiFi_connect",
|
||||
"params" : [
|
||||
["ssid","JsVar","The network SSID"],
|
||||
["password","JsVar","The password to the access point"],
|
||||
["gotIpCallback", "JsVar", "An optional callback invoked when we have an IP"]
|
||||
]
|
||||
}*/
|
||||
void jswrap_ESP8266WiFi_connect(JsVar *jsv_ssid, JsVar *jsv_password, JsVar *gotIpCallback) {
|
||||
// Check that the ssid and password values aren't obviously in error.
|
||||
if (jsv_ssid == NULL || !jsvIsString(jsv_ssid)) {
|
||||
jsExceptionHere(JSET_ERROR, "No SSID.");
|
||||
return;
|
||||
}
|
||||
if (jsv_password == NULL || !jsvIsString(jsv_password)) {
|
||||
jsExceptionHere(JSET_ERROR, "No password.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that if a callback function was supplied that we actually have a callback function.
|
||||
if (gotIpCallback != NULL && !jsvIsUndefined(gotIpCallback) && !jsvIsFunction(gotIpCallback)) {
|
||||
gotIpCallback = NULL;
|
||||
jsExceptionHere(JSET_ERROR, "A callback function was supplied that is not a function.");
|
||||
return;
|
||||
}
|
||||
if (jsvIsUndefined(gotIpCallback) || jsvIsNull(gotIpCallback)) {
|
||||
gotIpCallback = NULL;
|
||||
}
|
||||
|
||||
// Set the global which is the gotIP callback
|
||||
if (jsGotIpCallback != NULL) {
|
||||
jsvUnLock(jsGotIpCallback);
|
||||
jsGotIpCallback = NULL;
|
||||
}
|
||||
if (gotIpCallback != NULL) {
|
||||
jsGotIpCallback = jsvLockAgainSafe(gotIpCallback);
|
||||
}
|
||||
|
||||
// Create strings from the JsVars for the ESP8266 API calls.
|
||||
char ssid[33];
|
||||
int len = jsvGetString(jsv_ssid, ssid, sizeof(ssid)-1);
|
||||
ssid[len]='\0';
|
||||
char password[65];
|
||||
len = jsvGetString(jsv_password, password, sizeof(password)-1);
|
||||
password[len]='\0';
|
||||
|
||||
jsiConsolePrintf("jswrap_ESP8266WiFi_connect: %s - %s\r\n", ssid, password);
|
||||
|
||||
// Set the WiFi mode of the ESP8266
|
||||
wifi_set_opmode_current(STATION_MODE);
|
||||
|
||||
struct station_config stationConfig;
|
||||
memset(&stationConfig, 0, sizeof(stationConfig));
|
||||
os_strncpy((char *)stationConfig.ssid, ssid, 32);
|
||||
if (password != NULL) {
|
||||
os_strncpy((char *)stationConfig.password, password, 64);
|
||||
} else {
|
||||
os_strcpy((char *)stationConfig.password, "");
|
||||
}
|
||||
|
||||
// Set the WiFi configuration
|
||||
wifi_station_set_config(&stationConfig);
|
||||
|
||||
// Register the event handler
|
||||
wifi_set_event_handler_cb(wifiEventHandler);
|
||||
|
||||
wifi_station_connect();
|
||||
} // End of jswrap_ESP8266WiFi_connect
|
||||
|
||||
|
||||
/**
|
||||
* \brief Become an access point.
|
||||
* When we call this function we are instructing the ESP8266 to set itself up as an
|
||||
* access point to allow other WiFi stations to connect to it. In order to be an access
|
||||
* point, the ESP8266 needs to know the SSID it should use as well as the password used
|
||||
* to allow clients to connect.
|
||||
*
|
||||
* Parameters:
|
||||
* - `jsv_ssid` - The network identity that the access point will advertize itself as.
|
||||
* - `jsv_password` - The password a station will need to connect to the
|
||||
* access point.
|
||||
*
|
||||
* Notes:
|
||||
* - How about if the password is not supplied, NULL or empty then we set ourselves
|
||||
* up using an Open authentication mechanism?
|
||||
* - Add support for hidden SSIDs.
|
||||
*
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "beAccessPoint",
|
||||
"generate" : "jswrap_ESP8266WiFi_beAccessPoint",
|
||||
"params" : [
|
||||
["jsv_ssid","JsVar","The network SSID"],
|
||||
["jsv_password","JsVar","The password to allow stations to connect to the access point"]
|
||||
]
|
||||
}*/
|
||||
void jswrap_ESP8266WiFi_beAccessPoint(
|
||||
JsVar *jsv_ssid, //!< The network identity that the access point will advertize itself as.
|
||||
JsVar *jsv_password //!< The password a station will need to connect to the access point.
|
||||
) {
|
||||
// Validate that the SSID and password are somewhat useful.
|
||||
if (jsv_ssid == NULL || !jsvIsString(jsv_ssid)) {
|
||||
jsExceptionHere(JSET_ERROR, "No SSID.");
|
||||
return;
|
||||
}
|
||||
if (jsv_password == NULL || !jsvIsString(jsv_password)) {
|
||||
jsExceptionHere(JSET_ERROR, "No password.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create strings from the JsVars for the ESP8266 API calls.
|
||||
char ssid[33];
|
||||
int len = jsvGetString(jsv_ssid, ssid, sizeof(ssid)-1);
|
||||
ssid[len]='\0';
|
||||
char password[65];
|
||||
len = jsvGetString(jsv_password, password, sizeof(password)-1);
|
||||
password[len]='\0';
|
||||
|
||||
// Define that we are in Soft AP mode.
|
||||
wifi_set_opmode_current(SOFTAP_MODE);
|
||||
|
||||
// Build our SoftAP configuration details
|
||||
struct softap_config softApConfig;
|
||||
memset(&softApConfig, 0, sizeof(softApConfig));
|
||||
|
||||
os_strcpy((char *)softApConfig.ssid, ssid);
|
||||
os_strcpy((char *)softApConfig.password, password);
|
||||
softApConfig.ssid_len = 0; // Null terminated SSID
|
||||
softApConfig.authmode = AUTH_WPA2_PSK;
|
||||
softApConfig.ssid_hidden = 0; // Not hidden.
|
||||
softApConfig.max_connection = 4; // Maximum number of connections.
|
||||
|
||||
// Set the WiFi configuration.
|
||||
int rc = wifi_softap_set_config_current(&softApConfig);
|
||||
if (rc != 1) {
|
||||
jsExceptionHere(JSET_ERROR, "Error setting ESP8266 softap config.");
|
||||
}
|
||||
} // End of jswrap_ESP8266WiFi_beAccessPoint
|
||||
|
||||
|
||||
/**
|
||||
* \brief Determine the list of access points available to us.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "getAccessPoints",
|
||||
"generate" : "jswrap_ESP8266WiFi_getAccessPoints",
|
||||
"params" : [
|
||||
["callback","JsVar","Function to call back when access points retrieved."]
|
||||
]
|
||||
}*/
|
||||
void jswrap_ESP8266WiFi_getAccessPoints(
|
||||
JsVar *callback //!< Function to call back when access points retrieved.
|
||||
) {
|
||||
jsiConsolePrint("> ESP8266WiFi_getAccessPoints\n");
|
||||
if (callback == NULL || !jsvIsFunction(callback)) {
|
||||
jsExceptionHere(JSET_ERROR, "No callback.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the callback for the scan
|
||||
jsScanCallback = jsvLockAgainSafe(callback);
|
||||
|
||||
// Ask the ESP8266 to perform a network scan after first entering
|
||||
// station mode. This will result in an eventual callback which is where
|
||||
// Ensure we are in station mode
|
||||
wifi_set_opmode_current(STATION_MODE);
|
||||
|
||||
// Request a scan of the network calling "scanCB" on completion
|
||||
wifi_station_scan(NULL, scanCB);
|
||||
|
||||
jsiConsolePrint("< ESP8266WiFi_getAccessPoints\n");
|
||||
} // End of jswrap_ESP8266WiFi_getAccessPoints
|
||||
|
||||
|
||||
/**
|
||||
* \brief Disconnect the station from the access point.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "disconnect",
|
||||
"generate" : "jswrap_ESP8266WiFi_disconnect"
|
||||
}*/
|
||||
void jswrap_ESP8266WiFi_disconnect() {
|
||||
wifi_station_disconnect();
|
||||
} // End of jswrap_ESP8266WiFi_disconnect
|
||||
|
||||
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "restart",
|
||||
"generate" : "jswrap_ESP8266WiFi_restart"
|
||||
}*/
|
||||
void jswrap_ESP8266WiFi_restart() {
|
||||
system_restart();
|
||||
} // End of jswrap_ESP8266WiFi_restart
|
||||
|
||||
|
||||
/**
|
||||
* \brief Register a callback function that will be invoked when a WiFi event is detected.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "onWiFiEvent",
|
||||
"generate" : "jswrap_ESP8266WiFi_onWiFiEvent",
|
||||
"params" : [
|
||||
["callback","JsVar","WiFi event callback"]
|
||||
]
|
||||
}*/
|
||||
void jswrap_ESP8266WiFi_onWiFiEvent(
|
||||
JsVar *callback //!< WiFi event callback.
|
||||
) {
|
||||
// If the callback is null
|
||||
if (callback == NULL || jsvIsNull(callback)) {
|
||||
if (jsWiFiEventCallback != NULL) {
|
||||
jsvUnLock(jsWiFiEventCallback);
|
||||
}
|
||||
jsWiFiEventCallback = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!jsvIsFunction(callback)) {
|
||||
jsExceptionHere(JSET_ERROR, "No callback.");
|
||||
return;
|
||||
}
|
||||
|
||||
// We are about to save a new global WiFi even callback handler. If we have previously
|
||||
// had one, we need to unlock it so that we don't leak memory.
|
||||
if (jsWiFiEventCallback != NULL) {
|
||||
jsvUnLock(jsWiFiEventCallback);
|
||||
}
|
||||
|
||||
// Save the global WiFi event callback handler.
|
||||
jsWiFiEventCallback = jsvLockAgainSafe(callback);
|
||||
|
||||
// Register
|
||||
wifi_set_event_handler_cb(wifiEventHandler);
|
||||
} // End of jswrap_ESP8266WiFi_onWiFiEvent
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set whether or not the ESP8266 will perform an auto connect on startup.
|
||||
* A value of true means it will while a value of false means it won't.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "setAutoConnect",
|
||||
"generate" : "jswrap_ESP8266WiFi_setAutoConnect",
|
||||
"params" : [
|
||||
["autoconnect","JsVar","True if we wish to auto connect."]
|
||||
]
|
||||
}*/
|
||||
void jswrap_ESP8266WiFi_setAutoConnect(
|
||||
JsVar *autoconnect //!< True if we wish to auto connect.
|
||||
) {
|
||||
os_printf("Auto connect is: %d\n", (int)autoconnect);
|
||||
// Check that we have been passed a boolean ... if not, nothing to do here.
|
||||
if (!jsvIsBoolean(autoconnect)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 newValue = jsvGetBool(autoconnect);
|
||||
os_printf("New value: %d\n", newValue);
|
||||
os_printf("jswrap_ESP8266WiFi_setAutoConnect -> Something breaks here :-(\n");
|
||||
|
||||
uart_rx_intr_disable(0);
|
||||
wifi_station_set_auto_connect(newValue);
|
||||
uart_rx_intr_disable(1);
|
||||
os_printf("Autoconnect changed\n");
|
||||
} // End of jswrap_ESP8266WiFi_setAutoconnect
|
||||
|
||||
|
||||
/**
|
||||
* \brief Retrieve whether or not the ESP8266 will perform an auto connect on startup.
|
||||
* A value of 1 means it will while a value of zero means it won't.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "getAutoConnect",
|
||||
"generate" : "jswrap_ESP8266WiFi_getAutoConnect",
|
||||
"return" : ["JsVar","A boolean representing our auto connect status"]
|
||||
}*/
|
||||
JsVar *jswrap_ESP8266WiFi_getAutoConnect() {
|
||||
uint8 result = wifi_station_get_auto_connect();
|
||||
return jsvNewFromBool(result);
|
||||
} // End of jswrap_ESP8266WiFi_getAutoconnect
|
||||
|
||||
|
||||
/**
|
||||
* \brief Retrieve the reset information that is stored when event the ESP8266 resets.
|
||||
* The result will be a JS object containing the details.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "getRstInfo",
|
||||
"generate" : "jswrap_ESP8266WiFi_getRstInfo",
|
||||
"return" : ["JsVar","A Restart Object"],
|
||||
"return_object" : "Restart"
|
||||
}*/
|
||||
JsVar *jswrap_ESP8266WiFi_getRstInfo() {
|
||||
struct rst_info* info = system_get_rst_info();
|
||||
JsVar *restartInfo = jspNewObject(NULL, "Restart");
|
||||
jsvUnLock(jsvObjectSetChild(restartInfo, "reason", jsvNewFromInteger(info->reason)));
|
||||
jsvUnLock(jsvObjectSetChild(restartInfo, "exccause", jsvNewFromInteger(info->exccause)));
|
||||
jsvUnLock(jsvObjectSetChild(restartInfo, "epc1", jsvNewFromInteger(info->epc1)));
|
||||
jsvUnLock(jsvObjectSetChild(restartInfo, "epc2", jsvNewFromInteger(info->epc2)));
|
||||
jsvUnLock(jsvObjectSetChild(restartInfo, "epc3", jsvNewFromInteger(info->epc3)));
|
||||
jsvUnLock(jsvObjectSetChild(restartInfo, "excvaddr", jsvNewFromInteger(info->excvaddr)));
|
||||
jsvUnLock(jsvObjectSetChild(restartInfo, "depc", jsvNewFromInteger(info->depc)));
|
||||
return restartInfo;
|
||||
} // End of jswrap_ESP8266WiFi_getRstInfo
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return an object that contains details about the state of the ESP8266.
|
||||
* - `sdkVersion` - Version of the SDK.
|
||||
* - `cpuFrequency` - CPU operating frequency.
|
||||
* - `freeHeap` - Amount of free heap.
|
||||
* - `maxCon` - Maximum number of concurrent connections.
|
||||
*
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "getState",
|
||||
"generate" : "jswrap_ESP8266WiFi_getState",
|
||||
"return" : ["JsVar","The state of the ESP8266"],
|
||||
"return_object" : "ESP8266State"
|
||||
}*/
|
||||
JsVar *jswrap_ESP8266WiFi_getState() {
|
||||
// Create a new variable and populate it with the properties of the ESP8266 that we
|
||||
// wish to return.
|
||||
JsVar *esp8266State = jspNewObject(NULL, "ESP8266State");
|
||||
jsvUnLock(jsvObjectSetChild(esp8266State, "sdkVersion", jsvNewFromString(system_get_sdk_version())));
|
||||
jsvUnLock(jsvObjectSetChild(esp8266State, "cpuFrequency", jsvNewFromInteger(system_get_cpu_freq())));
|
||||
jsvUnLock(jsvObjectSetChild(esp8266State, "freeHeap", jsvNewFromInteger(system_get_free_heap_size())));
|
||||
jsvUnLock(jsvObjectSetChild(esp8266State, "maxCon", jsvNewFromInteger(espconn_tcp_get_max_con())));
|
||||
return esp8266State;
|
||||
} // End of jswrap_ESP8266WiFi_getState
|
||||
|
||||
/**
|
||||
* \brief Return the value of an integer representation (4 bytes) of IP address
|
||||
* as a string.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "getAddressAsString",
|
||||
"generate" : "jswrap_ESP8266WiFi_getAddressAsString",
|
||||
"params" : [
|
||||
["address","JsVar","An integer value representing an IP address."]
|
||||
],
|
||||
"return" : ["JsVar","A String"]
|
||||
}*/
|
||||
JsVar *jswrap_ESP8266WiFi_getAddressAsString(
|
||||
JsVar *address //!< An integer value representing an IP address.
|
||||
) {
|
||||
if (!jsvIsInt(address)) {
|
||||
jsExceptionHere(JSET_ERROR, "No SSID.");
|
||||
return NULL;
|
||||
}
|
||||
uint32 iAddress = (uint32)jsvGetInteger(address);
|
||||
return networkGetAddressAsString((uint8 *)&iAddress, 4, 10, '.');
|
||||
} // End of jswrap_ESP8266WiFi_getAddressAsString
|
||||
|
||||
|
||||
/**
|
||||
* \brief Retrieve the IP information about this network interface and return a JS
|
||||
* object that contains its details.
|
||||
* The object will have the following properties defined upon it:
|
||||
* - `ip` - The IP address of the interface.
|
||||
* - `netmask` - The netmask of the interface.
|
||||
* - `gw` - The gateway to reach when transmitting through the interface.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "getIPInfo",
|
||||
"generate" : "jswrap_ESP8266WiFi_getIPInfo",
|
||||
"return" : ["JsVar","A IPInfo Object"],
|
||||
"return_object" : "IPInfo"
|
||||
}*/
|
||||
JsVar *jswrap_ESP8266WiFi_getIPInfo() {
|
||||
struct ip_info info;
|
||||
wifi_get_ip_info(0, &info);
|
||||
|
||||
JsVar *ipInfo = jspNewObject(NULL, "Restart");
|
||||
jsvUnLock(jsvObjectSetChild(ipInfo, "ip", jsvNewFromInteger(info.ip.addr)));
|
||||
jsvUnLock(jsvObjectSetChild(ipInfo, "netmask", jsvNewFromInteger(info.netmask.addr)));
|
||||
jsvUnLock(jsvObjectSetChild(ipInfo, "gw", jsvNewFromInteger(info.gw.addr)));
|
||||
return ipInfo;
|
||||
} // End of jswrap_ESP8266WiFi_getIPInfo
|
||||
|
||||
|
||||
/**
|
||||
* \brief Query the station configuration and return a JS object that represents the
|
||||
* current settings.
|
||||
* The object will have the following properties:
|
||||
*
|
||||
* - `ssid` - The network identity of the access point
|
||||
* - `password` - The password to use to connect to the access point
|
||||
*
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "getStationConfig",
|
||||
"generate" : "jswrap_ESP8266WiFi_getStationConfig",
|
||||
"return" : ["JsVar","A Station Config"],
|
||||
"return_object" : "StationConfig"
|
||||
}*/
|
||||
JsVar *jswrap_ESP8266WiFi_getStationConfig() {
|
||||
struct station_config config;
|
||||
wifi_station_get_config(&config);
|
||||
JsVar *jsConfig = jspNewObject(NULL, "StationConfig");
|
||||
//char ssid[33];
|
||||
//nullTerminateString(ssid, (char *)config.ssid, 32);
|
||||
jsvUnLock(jsvObjectSetChild(jsConfig, "ssid", jsvNewFromString((char *)config.ssid)));
|
||||
//char password[65];
|
||||
//nullTerminateString(password, (char *)config.password, 64);
|
||||
jsvUnLock(jsvObjectSetChild(jsConfig, "password", jsvNewFromString((char *)config.password)));
|
||||
return jsConfig;
|
||||
} // End of jswrap_ESP8266WiFi_getStationConfig
|
||||
|
||||
|
||||
/**
|
||||
* \brief Determine the list of connected stations and return them.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "getConnectedStations",
|
||||
"generate" : "jswrap_ESP8266WiFi_getConnectedStations",
|
||||
"return" : ["JsVar","An array of connected stations."]
|
||||
}*/
|
||||
JsVar *jswrap_ESP8266WiFi_getConnectedStations() {
|
||||
uint8 stationCount = wifi_softap_get_station_num();
|
||||
struct station_info *stationInfo = wifi_softap_get_station_info();
|
||||
JsVar *jsArray = jsvNewArray(NULL, 0);
|
||||
if (stationInfo != NULL) {
|
||||
while (stationInfo != NULL) {
|
||||
os_printf("Station IP: %d.%d.%d.%d\n", IP2STR(&(stationInfo->ip)));
|
||||
JsVar *jsStation = jsvNewWithFlags(JSV_OBJECT);
|
||||
jsvUnLock(jsvObjectSetChild(jsStation, "ip", jsvNewFromInteger(stationInfo->ip.addr)));
|
||||
jsvArrayPush(jsArray, jsStation);
|
||||
stationInfo = STAILQ_NEXT(stationInfo, next);
|
||||
}
|
||||
wifi_softap_free_station_info();
|
||||
}
|
||||
return jsArray;
|
||||
} // End of jswrap_ESP8266WiFi_getConnectedStations
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the signal strength.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "getRSSI",
|
||||
"generate" : "jswrap_ESP8266WiFi_getRSSI",
|
||||
"return" : ["JsVar","An integer representing the signal strength."]
|
||||
}*/
|
||||
JsVar *jswrap_ESP8266WiFi_getRSSI() {
|
||||
int rssi = wifi_station_get_rssi();
|
||||
return jsvNewFromInteger(rssi);
|
||||
} // End of jswrap_ESP8266WiFi_getRSSI
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialize the ESP8266 environment.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "init",
|
||||
"generate" : "jswrap_ESP8266WiFi_init"
|
||||
}*/
|
||||
void jswrap_ESP8266WiFi_init() {
|
||||
os_printf("> jswrap_ESP8266WiFi_init\n");
|
||||
netInit_esp8266_board();
|
||||
setupJsNetwork();
|
||||
networkState = NETWORKSTATE_ONLINE;
|
||||
os_printf("< jswrap_ESP8266WiFi_init\n");
|
||||
} // End of jswrap_ESP8266WiFi_init
|
||||
|
||||
|
||||
/**
|
||||
* Return the ESP8266 connection status.
|
||||
* This is an integer value defined as:
|
||||
* - 0 - STATION_IDLE
|
||||
* - 1 - STATION_CONNECTING
|
||||
* - 2 - STATION_WRONG_PASSWORD
|
||||
* - 3 - STATION_NO_AP_FOUND
|
||||
* - 4 - STATION_CONNECT_FAIL
|
||||
* - 5 - STATION_GOT_IP
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "getConnectStatus",
|
||||
"generate" : "jswrap_ESP8266WiFi_getConnectStatus",
|
||||
"return" : ["JsVar","A connection status"]
|
||||
}
|
||||
|
||||
Retrieve the connection status. The return is an object that contains:
|
||||
|
||||
* status - The status code from ESP8266
|
||||
* statusMsg - The description of the code
|
||||
|
||||
*/
|
||||
JsVar *jswrap_ESP8266WiFi_getConnectStatus() {
|
||||
// Ask ESP8266 for the connection status
|
||||
uint8 status = wifi_station_get_connect_status();
|
||||
|
||||
// Create a JS variable to return
|
||||
JsVar *var = jsvNewWithFlags(JSV_OBJECT);
|
||||
|
||||
// Populate the return JS variable with a property called "status"
|
||||
JsVar *jsStatus = jsvNewFromInteger(status);
|
||||
//jsvUnLock(jsStatus);
|
||||
jsvUnLock(jsvObjectSetChild(var, "status", jsStatus));
|
||||
|
||||
// Populate the return JS variable with a property called "statusMsg"
|
||||
char *statusMsg;
|
||||
switch(status) {
|
||||
case STATION_IDLE:
|
||||
statusMsg = "STATION_IDLE";
|
||||
break;
|
||||
case STATION_CONNECTING:
|
||||
statusMsg = "STATION_CONNECTING";
|
||||
break;
|
||||
case STATION_WRONG_PASSWORD:
|
||||
statusMsg = "STATION_WRONG_PASSWORD";
|
||||
break;
|
||||
case STATION_NO_AP_FOUND:
|
||||
statusMsg = "STATION_NO_AP_FOUND";
|
||||
break;
|
||||
case STATION_CONNECT_FAIL:
|
||||
statusMsg = "STATION_CONNECT_FAIL";
|
||||
break;
|
||||
case STATION_GOT_IP:
|
||||
statusMsg = "STATION_GOT_IP";
|
||||
break;
|
||||
default:
|
||||
statusMsg = "*** Unknown ***";
|
||||
}
|
||||
JsVar *jsStatusMsg = jsvNewFromString(statusMsg);
|
||||
//jsvUnLock(jsStatusMsg);
|
||||
jsvUnLock(jsvObjectSetChild(var, "statusMsg", jsStatusMsg));
|
||||
//jsvUnLock(var);
|
||||
return var;
|
||||
} // End of jswrap_ESP8266WiFi_getConnectStatus
|
||||
|
||||
|
||||
/**
|
||||
* Test: Perform a socket connection to a partner system.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "socketConnect",
|
||||
"generate" : "jswrap_ESP8266WiFi_socketConnect",
|
||||
"params" : [
|
||||
["options","JsVar","Some kind of options."],
|
||||
["callback","JsVar","Some kind of callback."]
|
||||
],
|
||||
"return" : ["JsVar","A connection object"]
|
||||
}*/
|
||||
JsVar *jswrap_ESP8266WiFi_socketConnect(
|
||||
JsVar *options, //!< Some kind of options.
|
||||
JsVar *callback //!< Some kind of callback.
|
||||
) {
|
||||
os_printf("Network state = %d\n", networkState);
|
||||
JsVar *ret = jswrap_net_connect(options, callback, ST_NORMAL);
|
||||
return ret;
|
||||
} // End of jswrap_ESP8266WiFi_socketConnect
|
||||
|
||||
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "socketEnd",
|
||||
"generate" : "jswrap_ESP8266WiFi_socketEnd",
|
||||
"params" : [
|
||||
["socket","JsVar","The socket to be closed."],
|
||||
["data","JsVar","Optional data to be sent before close."]
|
||||
]
|
||||
}*/
|
||||
void jswrap_ESP8266WiFi_socketEnd(
|
||||
JsVar *socket, //!< The socket to be closed.
|
||||
JsVar *data //!< Optional data to be sent before close.
|
||||
) {
|
||||
jswrap_net_socket_end(socket, data);
|
||||
} // End of jswrap_ESP8266WiFi_socketEnd
|
||||
|
||||
|
||||
/**
|
||||
* \brief Perform a network ping request.
|
||||
* The parameter can be either a String or a numeric IP address.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "ping",
|
||||
"generate" : "jswrap_ESP8266WiFi_ping",
|
||||
"params" : [
|
||||
["ipAddr","JsVar","A string or integer representation of an IP address."],
|
||||
["pingCallback", "JsVar", "Optional callback function."]
|
||||
]
|
||||
}*/
|
||||
void jswrap_ESP8266WiFi_ping(
|
||||
JsVar *ipAddr, //!< A string or integer representation of an IP address.
|
||||
JsVar *pingCallback //!< Optional callback function.
|
||||
) {
|
||||
// If the parameter is a string, get the IP address from the string
|
||||
// representation.
|
||||
if (jsvIsString(ipAddr)) {
|
||||
char ipString[20];
|
||||
int len = jsvGetString(ipAddr, ipString, sizeof(ipString)-1);
|
||||
ipString[len] = '\0';
|
||||
pingOpt.ip = networkParseIPAddress(ipString);
|
||||
if (pingOpt.ip == 0) {
|
||||
jsExceptionHere(JSET_ERROR, "Not a valid IP address.");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
// If the parameter is an integer, treat it as an IP address.
|
||||
if (jsvIsInt(ipAddr)) {
|
||||
pingOpt.ip = jsvGetInteger(ipAddr);
|
||||
} else
|
||||
// The parameter was neither a string nor an IP address and hence we don't
|
||||
// know how to get the IP address of the partner to ping so throw an
|
||||
// exception.
|
||||
{
|
||||
jsExceptionHere(JSET_ERROR, "IP address must be string or integer.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (jsvIsUndefined(pingCallback) || jsvIsNull(pingCallback)) {
|
||||
if (jsPingCallback != NULL) {
|
||||
jsvUnLock(jsPingCallback);
|
||||
}
|
||||
jsPingCallback = NULL;
|
||||
} else if (!jsvIsFunction(pingCallback)) {
|
||||
jsExceptionHere(JSET_ERROR, "Callback is not a function.");
|
||||
return;
|
||||
} else {
|
||||
if (jsPingCallback != NULL) {
|
||||
jsvUnLock(jsPingCallback);
|
||||
}
|
||||
jsPingCallback = pingCallback;
|
||||
jsvLockAgainSafe(jsPingCallback);
|
||||
}
|
||||
|
||||
// We now have an IP address to ping ... so ping.
|
||||
memset(&pingOpt, 0, sizeof(pingOpt));
|
||||
pingOpt.count = 5;
|
||||
pingOpt.recv_function = pingRecvCB;
|
||||
ping_start(&pingOpt);
|
||||
} // End of jswrap_ESP8266WiFi_ping
|
||||
|
||||
|
||||
/**
|
||||
* \brief Dump the data in the socket.
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "dumpSocket",
|
||||
"generate" : "jswrap_ESP8266WiFi_dumpSocket",
|
||||
"params" : [
|
||||
["socketId","JsVar","The socket to be dumped."]
|
||||
]
|
||||
}*/
|
||||
|
||||
void jswrap_ESP8266WiFi_dumpSocket(
|
||||
JsVar *socketId //!< The socket to be dumped.
|
||||
) {
|
||||
esp8266_dumpSocket(jsvGetInteger(socketId)-1);
|
||||
} // End of jswrap_ESP8266WiFi_dumpSocket
|
||||
|
||||
/**
|
||||
* \brief Null terminate a string.
|
||||
*/
|
||||
static char *nullTerminateString(char *target, char *source, int sourceLength) {
|
||||
os_strncpy(target, source, sourceLength);
|
||||
target[sourceLength-1] = '\0';
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void setupJsNetwork() {
|
||||
JsNetwork net;
|
||||
networkCreate(&net, JSNETWORKTYPE_ESP8266_BOARD);
|
||||
networkSet(&net);
|
||||
} // End of setupJsNetwork
|
||||
|
||||
|
||||
/**
|
||||
* \brief Handle receiving a response from a ping reply.
|
||||
* If a callback function has been supplied we invoked that callback by queuing it for future
|
||||
* execution. A parameter is supplied to the callback which is a JavaScript object that contains:
|
||||
* - totalCount
|
||||
* - totalBytes
|
||||
* - totalTime
|
||||
* - respTime
|
||||
* - seqNo
|
||||
* - timeoutCount
|
||||
* - bytes
|
||||
* - error
|
||||
*/
|
||||
static void pingRecvCB(void *pingOpt, void *pingResponse) {
|
||||
struct ping_resp *pingResp = (struct ping_resp *)pingResponse;
|
||||
os_printf("Received a ping response!\n");
|
||||
if (jsPingCallback != NULL) {
|
||||
JsVar *jsPingResponse = jspNewObject(NULL, "PingResponse");
|
||||
jsvUnLock(jsvObjectSetChild(jsPingResponse, "totalCount", jsvNewFromInteger(pingResp->total_count)));
|
||||
jsvUnLock(jsvObjectSetChild(jsPingResponse, "totalBytes", jsvNewFromInteger(pingResp->total_bytes)));
|
||||
jsvUnLock(jsvObjectSetChild(jsPingResponse, "totalTime", jsvNewFromInteger(pingResp->total_time)));
|
||||
jsvUnLock(jsvObjectSetChild(jsPingResponse, "respTime", jsvNewFromInteger(pingResp->resp_time)));
|
||||
jsvUnLock(jsvObjectSetChild(jsPingResponse, "seqNo", jsvNewFromInteger(pingResp->seqno)));
|
||||
jsvUnLock(jsvObjectSetChild(jsPingResponse, "timeoutCount", jsvNewFromInteger(pingResp->timeout_count)));
|
||||
jsvUnLock(jsvObjectSetChild(jsPingResponse, "bytes", jsvNewFromInteger(pingResp->bytes)));
|
||||
jsvUnLock(jsvObjectSetChild(jsPingResponse, "error", jsvNewFromInteger(pingResp->ping_err)));
|
||||
JsVar *params[1];
|
||||
params[0] = jsPingResponse;
|
||||
jsiQueueEvents(NULL, jsPingCallback, params, 1);
|
||||
} // End of we have a callback function
|
||||
} // End of pingRecvCB
|
||||
|
||||
|
||||
/**
|
||||
* \brief Callback function that is invoked at the culmination of a scan.
|
||||
*/
|
||||
static void scanCB(void *arg, STATUS status) {
|
||||
/**
|
||||
* Create a JsVar that is an array of JS objects where each JS object represents a
|
||||
* retrieved access point set of information. The structure of a record will be:
|
||||
* o authMode
|
||||
* o isHidden
|
||||
* o rssi
|
||||
* o channel
|
||||
* o ssid
|
||||
* When the array has been built, invoke the callback function passing in the array
|
||||
* of records.
|
||||
*/
|
||||
|
||||
// Create the Empty JS array that will be passed as a parameter to the callback.
|
||||
JsVar *accessPointArray = jsvNewArray(NULL, 0);
|
||||
struct bss_info *bssInfo;
|
||||
|
||||
bssInfo = (struct bss_info *)arg;
|
||||
// skip the first in the chain … it is invalid
|
||||
bssInfo = STAILQ_NEXT(bssInfo, next);
|
||||
while(bssInfo != NULL) {
|
||||
// Add a new object to the JS array that will be passed as a parameter to
|
||||
// the callback. The ESP8266 bssInfo structure contains the following:
|
||||
// ---
|
||||
// uint8 bssid[6]
|
||||
// uint8 ssid[32]
|
||||
// uint8 channel
|
||||
// sint8 rssi – The received signal strength indication
|
||||
// AUTH_MODE authmode
|
||||
// Open = 0
|
||||
// WEP = 1
|
||||
// WPA_PSK = 2
|
||||
// WPA2_PSK = 3
|
||||
// WPA_WPA2_PSK = 4
|
||||
// uint8 is_hidden
|
||||
// sint16 freq_offset
|
||||
// ---
|
||||
// Create, populate and add a child ...
|
||||
JsVar *currentAccessPoint = jspNewObject(NULL, "AccessPoint");
|
||||
jsvUnLock(jsvObjectSetChild(currentAccessPoint, "rssi", jsvNewFromInteger(bssInfo->rssi)));
|
||||
jsvUnLock(jsvObjectSetChild(currentAccessPoint, "channel", jsvNewFromInteger(bssInfo->channel)));
|
||||
jsvUnLock(jsvObjectSetChild(currentAccessPoint, "authMode", jsvNewFromInteger(bssInfo->authmode)));
|
||||
jsvUnLock(jsvObjectSetChild(currentAccessPoint, "isHidden", jsvNewFromBool(bssInfo->is_hidden)));
|
||||
// The SSID may **NOT** be NULL terminated ... so handle that.
|
||||
char ssid[sizeof(bssInfo->ssid) + 1];
|
||||
os_strncpy((char *)ssid, (char *)bssInfo->ssid, sizeof(bssInfo->ssid));
|
||||
ssid[sizeof(ssid)-1] = '\0';
|
||||
jsvUnLock(jsvObjectSetChild(currentAccessPoint, "ssid", jsvNewFromString(ssid)));
|
||||
|
||||
// Add the new record to the array
|
||||
jsvArrayPush(accessPointArray, currentAccessPoint);
|
||||
|
||||
os_printf("ssid: %s\n", bssInfo->ssid);
|
||||
bssInfo = STAILQ_NEXT(bssInfo, next);
|
||||
} // End of loop over the records.
|
||||
|
||||
// We have now completed the scan callback, so now we can invoke the JS callback.
|
||||
JsVar *params[1];
|
||||
params[0] = accessPointArray;
|
||||
jsiQueueEvents(NULL, jsScanCallback, params, 1);
|
||||
jsvUnLock(jsScanCallback);
|
||||
} // End of scanCB
|
||||
|
||||
|
||||
/**
|
||||
* \brief Invoke the JavaScript callback to notify the program that an ESP8266
|
||||
* WiFi event has occurred.
|
||||
*/
|
||||
static void sendWifiEvent(uint32 eventType, JsVar *details) {
|
||||
// We need to check that we actually have an event callback handler because
|
||||
// it might have been disabled/removed.
|
||||
if (jsWiFiEventCallback != NULL) {
|
||||
// Build a callback event.
|
||||
JsVar *params[2];
|
||||
params[0] = jsvNewFromInteger(eventType);
|
||||
params[1] = details;
|
||||
jsiQueueEvents(NULL, jsWiFiEventCallback, params, 2);
|
||||
}
|
||||
|
||||
if (jsGotIpCallback != NULL && eventType == EVENT_STAMODE_GOT_IP) {
|
||||
JsVar *params[2];
|
||||
params[0] = jsvNewFromInteger(eventType);
|
||||
params[1] = details;
|
||||
jsiQueueEvents(NULL, jsGotIpCallback, params, 2);
|
||||
// Once we have registered the callback, we can unlock and release
|
||||
// the variable as we are only calling it once.
|
||||
//jsvUnLock(jsGotIpCallback);
|
||||
//jsGotIpCallback = NULL;
|
||||
}
|
||||
} // End of sendWifiEvent
|
||||
|
||||
|
||||
/**
|
||||
* \brief ESP8266 WiFi Event handler.
|
||||
* This function is called by the ESP8266
|
||||
* environment when significant events happend related to the WiFi environment.
|
||||
* The event handler is registered with a call to wifi_set_event_handler_cb()
|
||||
* that is provided by the ESP8266 SDK.
|
||||
*/
|
||||
static void wifiEventHandler(System_Event_t *event) {
|
||||
switch(event->event) {
|
||||
case EVENT_STAMODE_CONNECTED:
|
||||
os_printf("Event: EVENT_STAMODE_CONNECTED\n");
|
||||
sendWifiEvent(event->event, jsvNewNull());
|
||||
break;
|
||||
case EVENT_STAMODE_DISCONNECTED:
|
||||
os_printf("Event: EVENT_STAMODE_DISCONNECTED\n");
|
||||
JsVar *details = jspNewObject(NULL, "EventDetails");
|
||||
jsvObjectSetChild(details, "reason", jsvNewFromInteger(event->event_info.disconnected.reason));
|
||||
char ssid[33];
|
||||
memcpy(ssid, event->event_info.disconnected.ssid, event->event_info.disconnected.ssid_len);
|
||||
ssid[ event->event_info.disconnected.ssid_len] = '\0';
|
||||
sendWifiEvent(event->event, details);
|
||||
break;
|
||||
case EVENT_STAMODE_AUTHMODE_CHANGE:
|
||||
os_printf("Event: EVENT_STAMODE_AUTHMODE_CHANGE\n");
|
||||
sendWifiEvent(event->event, jsvNewNull());
|
||||
break;
|
||||
case EVENT_STAMODE_GOT_IP:
|
||||
os_printf("Event: EVENT_STAMODE_GOT_IP\n");
|
||||
sendWifiEvent(event->event, jsvNewNull());
|
||||
break;
|
||||
case EVENT_SOFTAPMODE_STACONNECTED:
|
||||
os_printf("Event: EVENT_SOFTAPMODE_STACONNECTED\n");
|
||||
sendWifiEvent(event->event, jsvNewNull());
|
||||
break;
|
||||
case EVENT_SOFTAPMODE_STADISCONNECTED:
|
||||
os_printf("Event: EVENT_SOFTAPMODE_STADISCONNECTED\n");
|
||||
sendWifiEvent(event->event, jsvNewNull());
|
||||
break;
|
||||
default:
|
||||
os_printf("Unexpected event: %d\n", event->event);
|
||||
sendWifiEvent(event->event, jsvNewNull());
|
||||
break;
|
||||
}
|
||||
} // End of wifiEventHandler
|
||||
|
||||
/**
|
||||
* \brief Write an IP address as a dotted decimal string.
|
||||
*/
|
||||
// Note: This may be a duplicate ... it appears that we may have an existing function
|
||||
// in network.c which does exactly this and more!!
|
||||
//
|
||||
static void ipAddrToString(struct ip_addr addr, char *string) {
|
||||
os_sprintf(string, "%d.%d.%d.%d", ((char *)&addr)[0], ((char *)&addr)[1], ((char *)&addr)[2], ((char *)&addr)[3]);
|
||||
} // End of ipAddrToString
|
||||
|
||||
// End of file
|
||||
34
libs/network/esp8266/jswrap_esp8266.h
Normal file
34
libs/network/esp8266/jswrap_esp8266.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* jswrap_ESP8266WiFi.h
|
||||
*
|
||||
* Created on: Aug 26, 2015
|
||||
* Author: kolban
|
||||
*/
|
||||
|
||||
#ifndef LIBS_NETWORK_ESP8266_JSWRAP_ESP8266_H_
|
||||
#define LIBS_NETWORK_ESP8266_JSWRAP_ESP8266_H_
|
||||
#include "jsvar.h"
|
||||
|
||||
void jswrap_ESP8266WiFi_connect(JsVar *jsv_ssid, JsVar *jsv_password, JsVar *gotIpCallback);
|
||||
void jswrap_ESP8266WiFi_getAccessPoints(JsVar *callback);
|
||||
void jswrap_ESP8266WiFi_disconnect();
|
||||
void jswrap_ESP8266WiFi_restart();
|
||||
JsVar *jswrap_ESP8266WiFi_getRstInfo();
|
||||
JsVar *jswrap_ESP8266WiFi_getIPInfo();
|
||||
void jswrap_ESP8266WiFi_setAutoConnect(JsVar *autoconnect);
|
||||
JsVar *jswrap_ESP8266WiFi_getAutoConnect();
|
||||
JsVar *jswrap_ESP8266WiFi_getStationConfig();
|
||||
void jswrap_ESP8266WiFi_onWiFiEvent(JsVar *callback);
|
||||
JsVar *jswrap_ESP8266WiFi_getAddressAsString(JsVar *address);
|
||||
void jswrap_ESP8266WiFi_init();
|
||||
JsVar *jswrap_ESP8266WiFi_getConnectStatus();
|
||||
JsVar *jswrap_ESP8266WiFi_socketConnect(JsVar *options, JsVar *callback);
|
||||
void jswrap_ESP8266WiFi_socketEnd(JsVar *socket, JsVar *data);
|
||||
void jswrap_ESP8266WiFi_ping(JsVar *ipAddr, JsVar *pingCallback);
|
||||
void jswrap_ESP8266WiFi_beAccessPoint(JsVar *jsv_ssid, JsVar *jsv_password);
|
||||
JsVar *jswrap_ESP8266WiFi_getConnectedStations();
|
||||
JsVar *jswrap_ESP8266WiFi_getRSSI();
|
||||
JsVar *jswrap_ESP8266WiFi_getState();
|
||||
void jswrap_ESP8266WiFi_dumpSocket(JsVar *socketId);
|
||||
|
||||
#endif /* LIBS_NETWORK_ESP8266_JSWRAP_ESP8266_H_ */
|
||||
1187
libs/network/esp8266/network_esp8266.c
Normal file
1187
libs/network/esp8266/network_esp8266.c
Normal file
File diff suppressed because it is too large
Load Diff
23
libs/network/esp8266/network_esp8266.h
Normal file
23
libs/network/esp8266/network_esp8266.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* network_esp8266_board.h
|
||||
*
|
||||
* Created on: Aug 29, 2015
|
||||
* Author: kolban
|
||||
*/
|
||||
|
||||
#ifndef LIBS_NETWORK_ESP8266_NETWORK_ESP8266_H_
|
||||
#define LIBS_NETWORK_ESP8266_NETWORK_ESP8266_H_
|
||||
|
||||
#include "network.h"
|
||||
void netInit_esp8266_board();
|
||||
void netSetCallbacks_esp8266_board(JsNetwork *net);
|
||||
void esp8266_dumpSocket(int socketId);
|
||||
int net_ESP8266_BOARD_accept(JsNetwork *net, int serverSckt);
|
||||
int net_ESP8266_BOARD_recv(JsNetwork *net, int sckt, void *buf, size_t len);
|
||||
int net_ESP8266_BOARD_send(JsNetwork *net, int sckt, const void *buf, size_t len);
|
||||
void net_ESP8266_BOARD_idle(JsNetwork *net);
|
||||
bool net_ESP8266_BOARD_checkError(JsNetwork *net);
|
||||
int net_ESP8266_BOARD_createSocket(JsNetwork *net, uint32_t ipAddress, unsigned short port);
|
||||
void net_ESP8266_BOARD_closeSocket(JsNetwork *net, int sckt);
|
||||
void net_ESP8266_BOARD_gethostbyname(JsNetwork *net, char *hostName, uint32_t *outIp);
|
||||
#endif /* LIBS_NETWORK_ESP8266_NETWORK_ESP8266_H_ */
|
||||
17
targets/esp8266/ESP8266_board.h
Normal file
17
targets/esp8266/ESP8266_board.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* ESP8266_board.h
|
||||
*
|
||||
* Created on: Aug 25, 2015
|
||||
* Author: kolban
|
||||
*/
|
||||
|
||||
#ifndef TARGETS_ESP8266_ESP8266_BOARD_H_
|
||||
#define TARGETS_ESP8266_ESP8266_BOARD_H_
|
||||
#include <user_interface.h>
|
||||
// Define the task ids for the APP event handler
|
||||
#define TASK_APP_MAINLOOP ((os_signal_t)1)
|
||||
#define TASK_APP_RX_DATA ((os_signal_t)2)
|
||||
#define TASK_APP_QUEUE USER_TASK_PRIO_1
|
||||
|
||||
|
||||
#endif /* TARGETS_ESP8266_ESP8266_BOARD_H_ */
|
||||
2
targets/esp8266/docs/ESP8266.md
Normal file
2
targets/esp8266/docs/ESP8266.md
Normal file
@ -0,0 +1,2 @@
|
||||
# ESP8266
|
||||
This is where documentation on the ESP8266 target will be provided.
|
||||
226
targets/esp8266/driver/uart.h
Normal file
226
targets/esp8266/driver/uart.h
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* File : uart.h
|
||||
* Copyright (C) 2013 - 2016, Espressif Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of version 3 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef UART_APP_H
|
||||
#define UART_APP_H
|
||||
|
||||
#include "uart_register.h"
|
||||
#include "eagle_soc.h"
|
||||
#include "c_types.h"
|
||||
|
||||
|
||||
int getRXBuffer(char *pBuffer, int bufferLen);
|
||||
int uart_rx_discard();
|
||||
|
||||
|
||||
#define UART_TX_BUFFER_SIZE 256 //Ring buffer length of tx buffer
|
||||
#define UART_RX_BUFFER_SIZE 256 //Ring buffer length of rx buffer
|
||||
|
||||
#define UART_BUFF_EN 0 //use uart buffer , FOR UART0
|
||||
#define UART_SELFTEST 0 //set 1:enable the loop test demo for uart buffer, FOR UART0
|
||||
|
||||
#define UART_HW_RTS 0 //set 1: enable uart hw flow control RTS, PIN MTDO, FOR UART0
|
||||
#define UART_HW_CTS 0 //set1: enable uart hw flow contrl CTS , PIN MTCK, FOR UART0
|
||||
|
||||
|
||||
|
||||
|
||||
#define UART0 0
|
||||
#define UART1 1
|
||||
|
||||
|
||||
typedef enum {
|
||||
FIVE_BITS = 0x0,
|
||||
SIX_BITS = 0x1,
|
||||
SEVEN_BITS = 0x2,
|
||||
EIGHT_BITS = 0x3
|
||||
} UartBitsNum4Char;
|
||||
|
||||
typedef enum {
|
||||
ONE_STOP_BIT = 0x1,
|
||||
ONE_HALF_STOP_BIT = 0x2,
|
||||
TWO_STOP_BIT = 0x3
|
||||
} UartStopBitsNum;
|
||||
|
||||
typedef enum {
|
||||
NONE_BITS = 0x2,
|
||||
ODD_BITS = 1,
|
||||
EVEN_BITS = 0
|
||||
} UartParityMode;
|
||||
|
||||
typedef enum {
|
||||
STICK_PARITY_DIS = 0,
|
||||
STICK_PARITY_EN = 1
|
||||
} UartExistParity;
|
||||
|
||||
typedef enum {
|
||||
UART_None_Inverse = 0x0,
|
||||
UART_Rxd_Inverse = UART_RXD_INV,
|
||||
UART_CTS_Inverse = UART_CTS_INV,
|
||||
UART_Txd_Inverse = UART_TXD_INV,
|
||||
UART_RTS_Inverse = UART_RTS_INV,
|
||||
} UART_LineLevelInverse;
|
||||
|
||||
|
||||
typedef enum {
|
||||
BIT_RATE_300 = 300,
|
||||
BIT_RATE_600 = 600,
|
||||
BIT_RATE_1200 = 1200,
|
||||
BIT_RATE_2400 = 2400,
|
||||
BIT_RATE_4800 = 4800,
|
||||
BIT_RATE_9600 = 9600,
|
||||
BIT_RATE_19200 = 19200,
|
||||
BIT_RATE_38400 = 38400,
|
||||
BIT_RATE_57600 = 57600,
|
||||
BIT_RATE_74880 = 74880,
|
||||
BIT_RATE_115200 = 115200,
|
||||
BIT_RATE_230400 = 230400,
|
||||
BIT_RATE_460800 = 460800,
|
||||
BIT_RATE_921600 = 921600,
|
||||
BIT_RATE_1843200 = 1843200,
|
||||
BIT_RATE_3686400 = 3686400,
|
||||
} UartBautRate;
|
||||
|
||||
typedef enum {
|
||||
NONE_CTRL,
|
||||
HARDWARE_CTRL,
|
||||
XON_XOFF_CTRL
|
||||
} UartFlowCtrl;
|
||||
|
||||
typedef enum {
|
||||
USART_HardwareFlowControl_None = 0x0,
|
||||
USART_HardwareFlowControl_RTS = 0x1,
|
||||
USART_HardwareFlowControl_CTS = 0x2,
|
||||
USART_HardwareFlowControl_CTS_RTS = 0x3
|
||||
} UART_HwFlowCtrl;
|
||||
|
||||
typedef enum {
|
||||
EMPTY,
|
||||
UNDER_WRITE,
|
||||
WRITE_OVER
|
||||
} RcvMsgBuffState;
|
||||
|
||||
typedef struct {
|
||||
uint32 RcvBuffSize;
|
||||
uint8 *pRcvMsgBuff;
|
||||
uint8 *pWritePos;
|
||||
uint8 *pReadPos;
|
||||
uint8 TrigLvl; //JLU: may need to pad
|
||||
RcvMsgBuffState BuffState;
|
||||
} RcvMsgBuff;
|
||||
|
||||
typedef struct {
|
||||
uint32 TrxBuffSize;
|
||||
uint8 *pTrxBuff;
|
||||
} TrxMsgBuff;
|
||||
|
||||
typedef enum {
|
||||
BAUD_RATE_DET,
|
||||
WAIT_SYNC_FRM,
|
||||
SRCH_MSG_HEAD,
|
||||
RCV_MSG_BODY,
|
||||
RCV_ESC_CHAR,
|
||||
} RcvMsgState;
|
||||
|
||||
typedef struct {
|
||||
UartBautRate baut_rate;
|
||||
UartBitsNum4Char data_bits;
|
||||
UartExistParity exist_parity;
|
||||
UartParityMode parity;
|
||||
UartStopBitsNum stop_bits;
|
||||
UartFlowCtrl flow_ctrl;
|
||||
RcvMsgBuff rcv_buff;
|
||||
TrxMsgBuff trx_buff;
|
||||
RcvMsgState rcv_state;
|
||||
int received;
|
||||
int buff_uart_no; //indicate which uart use tx/rx buffer
|
||||
} UartDevice;
|
||||
|
||||
void uart_init(UartBautRate uart0_br, UartBautRate uart1_br);
|
||||
void uart0_sendStr(const char *str);
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
#define UART_FIFO_LEN 128 //define the tx fifo length
|
||||
#define UART_TX_EMPTY_THRESH_VAL 0x10
|
||||
|
||||
|
||||
struct UartBuffer{
|
||||
uint32 UartBuffSize;
|
||||
uint8 *pUartBuff;
|
||||
uint8 *pInPos;
|
||||
uint8 *pOutPos;
|
||||
STATUS BuffState;
|
||||
uint16 Space; //remanent space of the buffer
|
||||
uint8 TcpControl;
|
||||
struct UartBuffer * nextBuff;
|
||||
};
|
||||
|
||||
struct UartRxBuff{
|
||||
uint32 UartRxBuffSize;
|
||||
uint8 *pUartRxBuff;
|
||||
uint8 *pWritePos;
|
||||
uint8 *pReadPos;
|
||||
STATUS RxBuffState;
|
||||
uint32 Space; //remanent space of the buffer
|
||||
} ;
|
||||
|
||||
typedef enum {
|
||||
RUN = 0,
|
||||
BLOCK = 1,
|
||||
} TCPState;
|
||||
|
||||
//void ICACHE_FLASH_ATTR uart_test_rx();
|
||||
STATUS uart_tx_one_char(uint8 uart, uint8 TxChar);
|
||||
STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar);
|
||||
void uart1_sendStr_no_wait(const char *str);
|
||||
struct UartBuffer* Uart_Buf_Init();
|
||||
|
||||
|
||||
#if UART_BUFF_EN
|
||||
LOCAL void Uart_Buf_Cpy(struct UartBuffer* pCur, char* pdata , uint16 data_len);
|
||||
void uart_buf_free(struct UartBuffer* pBuff);
|
||||
void tx_buff_enq(char* pdata, uint16 data_len );
|
||||
LOCAL void tx_fifo_insert(struct UartBuffer* pTxBuff, uint8 data_len, uint8 uart_no);
|
||||
void tx_start_uart_buffer(uint8 uart_no);
|
||||
uint16 rx_buff_deq(char* pdata, uint16 data_len );
|
||||
void Uart_rx_buff_enq();
|
||||
#endif
|
||||
void uart_rx_intr_enable(uint8 uart_no);
|
||||
void uart_rx_intr_disable(uint8 uart_no);
|
||||
void uart0_tx_buffer(uint8 *buf, uint16 len);
|
||||
|
||||
//==============================================
|
||||
#define FUNC_UART0_CTS 4
|
||||
#define FUNC_U0CTS 4
|
||||
#define FUNC_U1TXD_BK 2
|
||||
#define UART_LINE_INV_MASK (0x3f<<19)
|
||||
void UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len);
|
||||
void UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num);
|
||||
void UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask);
|
||||
void UART_SetParity(uint8 uart_no, UartParityMode Parity_mode);
|
||||
void UART_SetBaudrate(uint8 uart_no,uint32 baud_rate);
|
||||
void UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh);
|
||||
void UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us); //do not use if tx flow control enabled
|
||||
void UART_ResetFifo(uint8 uart_no);
|
||||
void UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask);
|
||||
void UART_SetIntrEna(uint8 uart_no,uint32 ena_mask);
|
||||
void UART_SetPrintPort(uint8 uart_no);
|
||||
bool UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us);
|
||||
//==============================================
|
||||
|
||||
#endif
|
||||
|
||||
156
targets/esp8266/driver/uart_register.h
Normal file
156
targets/esp8266/driver/uart_register.h
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* File : uart_register.h
|
||||
* Copyright (C) 2013 - 2016, Espressif Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of version 3 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2010 - 2011 Espressif System
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UART_REGISTER_H_
|
||||
#define UART_REGISTER_H_
|
||||
|
||||
#define REG_UART_BASE(i) (0x60000000 + (i)*0xf00)
|
||||
//version value:32'h062000
|
||||
|
||||
#define UART_FIFO(i) (REG_UART_BASE(i) + 0x0)
|
||||
#define UART_RXFIFO_RD_BYTE 0x000000FF
|
||||
#define UART_RXFIFO_RD_BYTE_S 0
|
||||
|
||||
#define UART_INT_RAW(i) (REG_UART_BASE(i) + 0x4)
|
||||
#define UART_RXFIFO_TOUT_INT_RAW (BIT(8))
|
||||
#define UART_BRK_DET_INT_RAW (BIT(7))
|
||||
#define UART_CTS_CHG_INT_RAW (BIT(6))
|
||||
#define UART_DSR_CHG_INT_RAW (BIT(5))
|
||||
#define UART_RXFIFO_OVF_INT_RAW (BIT(4))
|
||||
#define UART_FRM_ERR_INT_RAW (BIT(3))
|
||||
#define UART_PARITY_ERR_INT_RAW (BIT(2))
|
||||
#define UART_TXFIFO_EMPTY_INT_RAW (BIT(1))
|
||||
#define UART_RXFIFO_FULL_INT_RAW (BIT(0))
|
||||
|
||||
#define UART_INT_ST(i) (REG_UART_BASE(i) + 0x8)
|
||||
#define UART_RXFIFO_TOUT_INT_ST (BIT(8))
|
||||
#define UART_BRK_DET_INT_ST (BIT(7))
|
||||
#define UART_CTS_CHG_INT_ST (BIT(6))
|
||||
#define UART_DSR_CHG_INT_ST (BIT(5))
|
||||
#define UART_RXFIFO_OVF_INT_ST (BIT(4))
|
||||
#define UART_FRM_ERR_INT_ST (BIT(3))
|
||||
#define UART_PARITY_ERR_INT_ST (BIT(2))
|
||||
#define UART_TXFIFO_EMPTY_INT_ST (BIT(1))
|
||||
#define UART_RXFIFO_FULL_INT_ST (BIT(0))
|
||||
|
||||
#define UART_INT_ENA(i) (REG_UART_BASE(i) + 0xC)
|
||||
#define UART_RXFIFO_TOUT_INT_ENA (BIT(8))
|
||||
#define UART_BRK_DET_INT_ENA (BIT(7))
|
||||
#define UART_CTS_CHG_INT_ENA (BIT(6))
|
||||
#define UART_DSR_CHG_INT_ENA (BIT(5))
|
||||
#define UART_RXFIFO_OVF_INT_ENA (BIT(4))
|
||||
#define UART_FRM_ERR_INT_ENA (BIT(3))
|
||||
#define UART_PARITY_ERR_INT_ENA (BIT(2))
|
||||
#define UART_TXFIFO_EMPTY_INT_ENA (BIT(1))
|
||||
#define UART_RXFIFO_FULL_INT_ENA (BIT(0))
|
||||
|
||||
#define UART_INT_CLR(i) (REG_UART_BASE(i) + 0x10)
|
||||
#define UART_RXFIFO_TOUT_INT_CLR (BIT(8))
|
||||
#define UART_BRK_DET_INT_CLR (BIT(7))
|
||||
#define UART_CTS_CHG_INT_CLR (BIT(6))
|
||||
#define UART_DSR_CHG_INT_CLR (BIT(5))
|
||||
#define UART_RXFIFO_OVF_INT_CLR (BIT(4))
|
||||
#define UART_FRM_ERR_INT_CLR (BIT(3))
|
||||
#define UART_PARITY_ERR_INT_CLR (BIT(2))
|
||||
#define UART_TXFIFO_EMPTY_INT_CLR (BIT(1))
|
||||
#define UART_RXFIFO_FULL_INT_CLR (BIT(0))
|
||||
|
||||
#define UART_CLKDIV(i) (REG_UART_BASE(i) + 0x14)
|
||||
#define UART_CLKDIV_CNT 0x000FFFFF
|
||||
#define UART_CLKDIV_S 0
|
||||
|
||||
#define UART_AUTOBAUD(i) (REG_UART_BASE(i) + 0x18)
|
||||
#define UART_GLITCH_FILT 0x000000FF
|
||||
#define UART_GLITCH_FILT_S 8
|
||||
#define UART_AUTOBAUD_EN (BIT(0))
|
||||
|
||||
#define UART_STATUS(i) (REG_UART_BASE(i) + 0x1C)
|
||||
#define UART_TXD (BIT(31))
|
||||
#define UART_RTSN (BIT(30))
|
||||
#define UART_DTRN (BIT(29))
|
||||
#define UART_TXFIFO_CNT 0x000000FF
|
||||
#define UART_TXFIFO_CNT_S 16
|
||||
#define UART_RXD (BIT(15))
|
||||
#define UART_CTSN (BIT(14))
|
||||
#define UART_DSRN (BIT(13))
|
||||
#define UART_RXFIFO_CNT 0x000000FF
|
||||
#define UART_RXFIFO_CNT_S 0
|
||||
|
||||
#define UART_CONF0(i) (REG_UART_BASE(i) + 0x20)
|
||||
#define UART_DTR_INV (BIT(24))
|
||||
#define UART_RTS_INV (BIT(23))
|
||||
#define UART_TXD_INV (BIT(22))
|
||||
#define UART_DSR_INV (BIT(21))
|
||||
#define UART_CTS_INV (BIT(20))
|
||||
#define UART_RXD_INV (BIT(19))
|
||||
#define UART_TXFIFO_RST (BIT(18))
|
||||
#define UART_RXFIFO_RST (BIT(17))
|
||||
#define UART_IRDA_EN (BIT(16))
|
||||
#define UART_TX_FLOW_EN (BIT(15))
|
||||
#define UART_LOOPBACK (BIT(14))
|
||||
#define UART_IRDA_RX_INV (BIT(13))
|
||||
#define UART_IRDA_TX_INV (BIT(12))
|
||||
#define UART_IRDA_WCTL (BIT(11))
|
||||
#define UART_IRDA_TX_EN (BIT(10))
|
||||
#define UART_IRDA_DPLX (BIT(9))
|
||||
#define UART_TXD_BRK (BIT(8))
|
||||
#define UART_SW_DTR (BIT(7))
|
||||
#define UART_SW_RTS (BIT(6))
|
||||
#define UART_STOP_BIT_NUM 0x00000003
|
||||
#define UART_STOP_BIT_NUM_S 4
|
||||
#define UART_BIT_NUM 0x00000003
|
||||
#define UART_BIT_NUM_S 2
|
||||
#define UART_PARITY_EN (BIT(1))
|
||||
#define UART_PARITY_EN_M 0x00000001
|
||||
#define UART_PARITY_EN_S 1
|
||||
#define UART_PARITY (BIT(0))
|
||||
#define UART_PARITY_M 0x00000001
|
||||
#define UART_PARITY_S 0
|
||||
|
||||
#define UART_CONF1(i) (REG_UART_BASE(i) + 0x24)
|
||||
#define UART_RX_TOUT_EN (BIT(31))
|
||||
#define UART_RX_TOUT_THRHD 0x0000007F
|
||||
#define UART_RX_TOUT_THRHD_S 24
|
||||
#define UART_RX_FLOW_EN (BIT(23))
|
||||
#define UART_RX_FLOW_THRHD 0x0000007F
|
||||
#define UART_RX_FLOW_THRHD_S 16
|
||||
#define UART_TXFIFO_EMPTY_THRHD 0x0000007F
|
||||
#define UART_TXFIFO_EMPTY_THRHD_S 8
|
||||
#define UART_RXFIFO_FULL_THRHD 0x0000007F
|
||||
#define UART_RXFIFO_FULL_THRHD_S 0
|
||||
|
||||
#define UART_LOWPULSE(i) (REG_UART_BASE(i) + 0x28)
|
||||
#define UART_LOWPULSE_MIN_CNT 0x000FFFFF
|
||||
#define UART_LOWPULSE_MIN_CNT_S 0
|
||||
|
||||
#define UART_HIGHPULSE(i) (REG_UART_BASE(i) + 0x2C)
|
||||
#define UART_HIGHPULSE_MIN_CNT 0x000FFFFF
|
||||
#define UART_HIGHPULSE_MIN_CNT_S 0
|
||||
|
||||
#define UART_PULSE_NUM(i) (REG_UART_BASE(i) + 0x30)
|
||||
#define UART_PULSE_NUM_CNT 0x0003FF
|
||||
#define UART_PULSE_NUM_CNT_S 0
|
||||
|
||||
#define UART_DATE(i) (REG_UART_BASE(i) + 0x78)
|
||||
#define UART_ID(i) (REG_UART_BASE(i) + 0x7C)
|
||||
|
||||
#endif // UART_REGISTER_H_INCLUDED
|
||||
|
||||
211
targets/esp8266/eagle.app.v6.0x10000.ld
Normal file
211
targets/esp8266/eagle.app.v6.0x10000.ld
Normal file
@ -0,0 +1,211 @@
|
||||
/* This linker script generated from xt-genldscripts.tpp for LSP . */
|
||||
/* Linker Script for ld -N */
|
||||
MEMORY
|
||||
{
|
||||
dport0_0_seg : org = 0x3FF00000, len = 0x10
|
||||
dram0_0_seg : org = 0x3FFE8000, len = 0x14000
|
||||
iram1_0_seg : org = 0x40100000, len = 0x8000
|
||||
irom0_0_seg : org = 0x40210000, len = 0x60000
|
||||
}
|
||||
|
||||
PHDRS
|
||||
{
|
||||
dport0_0_phdr PT_LOAD;
|
||||
dram0_0_phdr PT_LOAD;
|
||||
dram0_0_bss_phdr PT_LOAD;
|
||||
iram1_0_phdr PT_LOAD;
|
||||
irom0_0_phdr PT_LOAD;
|
||||
}
|
||||
|
||||
|
||||
/* Default entry point: */
|
||||
ENTRY(call_user_start)
|
||||
EXTERN(_DebugExceptionVector)
|
||||
EXTERN(_DoubleExceptionVector)
|
||||
EXTERN(_KernelExceptionVector)
|
||||
EXTERN(_NMIExceptionVector)
|
||||
EXTERN(_UserExceptionVector)
|
||||
PROVIDE(_memmap_vecbase_reset = 0x40000000);
|
||||
/* Various memory-map dependent cache attribute settings: */
|
||||
_memmap_cacheattr_wb_base = 0x00000110;
|
||||
_memmap_cacheattr_wt_base = 0x00000110;
|
||||
_memmap_cacheattr_bp_base = 0x00000220;
|
||||
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
|
||||
_memmap_cacheattr_wb_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_wba_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_wt_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_bp_trapnull = 0x2222222F;
|
||||
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
|
||||
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
|
||||
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
|
||||
_memmap_cacheattr_wb_allvalid = 0x22222112;
|
||||
_memmap_cacheattr_wt_allvalid = 0x22222112;
|
||||
_memmap_cacheattr_bp_allvalid = 0x22222222;
|
||||
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
.dport0.rodata : ALIGN(4)
|
||||
{
|
||||
_dport0_rodata_start = ABSOLUTE(.);
|
||||
*(.dport0.rodata)
|
||||
*(.dport.rodata)
|
||||
_dport0_rodata_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
.dport0.literal : ALIGN(4)
|
||||
{
|
||||
_dport0_literal_start = ABSOLUTE(.);
|
||||
*(.dport0.literal)
|
||||
*(.dport.literal)
|
||||
_dport0_literal_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
.dport0.data : ALIGN(4)
|
||||
{
|
||||
_dport0_data_start = ABSOLUTE(.);
|
||||
*(.dport0.data)
|
||||
*(.dport.data)
|
||||
_dport0_data_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
_data_start = ABSOLUTE(.);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
*(.jcr)
|
||||
_data_end = ABSOLUTE(.);
|
||||
} >dram0_0_seg :dram0_0_phdr
|
||||
|
||||
.rodata : ALIGN(4)
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
*(.sdk.version)
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
||||
*(.xt_except_table)
|
||||
*(.gcc_except_table)
|
||||
*(.gnu.linkonce.e.*)
|
||||
*(.gnu.version_r)
|
||||
*(.eh_frame)
|
||||
/* C++ constructor and destructor tables, properly ordered: */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
/* C++ exception handlers table: */
|
||||
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
|
||||
*(.xt_except_desc)
|
||||
*(.gnu.linkonce.h.*)
|
||||
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
||||
*(.xt_except_desc_end)
|
||||
*(.dynamic)
|
||||
*(.gnu.version_d)
|
||||
. = ALIGN(4); /* this table MUST be 4-byte aligned */
|
||||
_bss_table_start = ABSOLUTE(.);
|
||||
LONG(_bss_start)
|
||||
LONG(_bss_end)
|
||||
_bss_table_end = ABSOLUTE(.);
|
||||
_rodata_end = ABSOLUTE(.);
|
||||
} >dram0_0_seg :dram0_0_phdr
|
||||
|
||||
.bss ALIGN(8) (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
. = ALIGN (8);
|
||||
_bss_start = ABSOLUTE(.);
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
_bss_end = ABSOLUTE(.);
|
||||
_heap_start = ABSOLUTE(.);
|
||||
/* _stack_sentry = ALIGN(0x8); */
|
||||
} >dram0_0_seg :dram0_0_bss_phdr
|
||||
/* __stack = 0x3ffc8000; */
|
||||
|
||||
.text : ALIGN(4)
|
||||
{
|
||||
_stext = .;
|
||||
_text_start = ABSOLUTE(.);
|
||||
*(.UserEnter.text)
|
||||
. = ALIGN(16);
|
||||
*(.DebugExceptionVector.text)
|
||||
. = ALIGN(16);
|
||||
*(.NMIExceptionVector.text)
|
||||
. = ALIGN(16);
|
||||
*(.KernelExceptionVector.text)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN(16);
|
||||
*(.UserExceptionVector.text)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN(16);
|
||||
*(.DoubleExceptionVector.text)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN (16);
|
||||
*(.entry.text)
|
||||
*(.init.literal)
|
||||
*(.init)
|
||||
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||
*(.fini.literal)
|
||||
*(.fini)
|
||||
*(.gnu.version)
|
||||
_text_end = ABSOLUTE(.);
|
||||
_etext = .;
|
||||
} >iram1_0_seg :iram1_0_phdr
|
||||
|
||||
.lit4 : ALIGN(4)
|
||||
{
|
||||
_lit4_start = ABSOLUTE(.);
|
||||
*(*.lit4)
|
||||
*(.lit4.*)
|
||||
*(.gnu.linkonce.lit4.*)
|
||||
_lit4_end = ABSOLUTE(.);
|
||||
} >iram1_0_seg :iram1_0_phdr
|
||||
|
||||
.irom0.text : ALIGN(4)
|
||||
{
|
||||
_irom0_text_start = ABSOLUTE(.);
|
||||
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
|
||||
_irom0_text_end = ABSOLUTE(.);
|
||||
} >irom0_0_seg :irom0_0_phdr
|
||||
}
|
||||
|
||||
/* get ROM code address */
|
||||
INCLUDE "../ld/eagle.rom.addr.v6.ld"
|
||||
69
targets/esp8266/esp8266_board_utils.c
Normal file
69
targets/esp8266/esp8266_board_utils.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include <ets_sys.h>
|
||||
#include <osapi.h>
|
||||
#include <os_type.h>
|
||||
#include <user_interface.h>
|
||||
#include <espconn.h>
|
||||
#include <gpio.h>
|
||||
#include <mem.h>
|
||||
#include <espmissingincludes.h>
|
||||
|
||||
#define _GCC_WRAP_STDINT_H
|
||||
typedef long long int64_t;
|
||||
|
||||
#include "jsutils.h"
|
||||
|
||||
/**
|
||||
* \brief Convert an ESP8266 error code to a string.
|
||||
* Given an ESP8266 network error code, return a string representation
|
||||
* of the meaning of that code.
|
||||
* \return A string representation of an error code.
|
||||
*/
|
||||
const char *esp8266_errorToString(
|
||||
sint8 err //!< The error code to be transformed to a string.
|
||||
) {
|
||||
switch(err) {
|
||||
case ESPCONN_MEM:
|
||||
return "ESPCONN_MEM";
|
||||
case ESPCONN_TIMEOUT:
|
||||
return "ESPCONN_TIMEOUT";
|
||||
case ESPCONN_RTE:
|
||||
return "ESPCONN_RTE";
|
||||
case ESPCONN_INPROGRESS:
|
||||
return "ESPCONN_INPROGRESS";
|
||||
case ESPCONN_ABRT:
|
||||
return "ESPCONN_ABRT";
|
||||
case ESPCONN_RST:
|
||||
return "ESPCONN_RST";
|
||||
case ESPCONN_CLSD:
|
||||
return "ESPCONN_CLSD";
|
||||
case ESPCONN_CONN:
|
||||
return "ESPCONN_CONN";
|
||||
case ESPCONN_ARG:
|
||||
return "ESPCONN_ARG";
|
||||
case ESPCONN_ISCONN:
|
||||
return "ESPCONN_ISCONN";
|
||||
case ESPCONN_HANDSHAKE:
|
||||
return "ESPCONN_HANDSHAKE";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
} // End of errorToString
|
||||
|
||||
|
||||
/**
|
||||
* \brief Write a buffer of data to the console.
|
||||
* The buffer is pointed to by the buffer
|
||||
* parameter and will be written for the length parameter. This is useful because
|
||||
* unlike a string, the data does not have to be NULL terminated.
|
||||
*/
|
||||
void esp8266_board_writeString(
|
||||
uint8 *buffer, //!< The start of the buffer to write.
|
||||
size_t length //!< The length of the buffer to write.
|
||||
) {
|
||||
assert(length==0 || buffer != NULL);
|
||||
|
||||
for (size_t i=0; i<length; i++) {
|
||||
os_printf("%c", buffer[i]);
|
||||
}
|
||||
} // End of esp8266_board_writeString
|
||||
// End of file
|
||||
15
targets/esp8266/esp8266_board_utils.h
Normal file
15
targets/esp8266/esp8266_board_utils.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* esp8266_board_utils.h
|
||||
*
|
||||
* Created on: Sep 3, 2015
|
||||
* Author: kolban
|
||||
*/
|
||||
|
||||
#ifndef TARGETS_ESP8266_ESP8266_BOARD_UTILS_H_
|
||||
#define TARGETS_ESP8266_ESP8266_BOARD_UTILS_H_
|
||||
|
||||
// Return a string representation of an ESP8266 error.
|
||||
const char *esp8266_errorToString(sint8 err);
|
||||
void esp8266_board_writeString(uint8 *buffer, size_t length);
|
||||
|
||||
#endif /* TARGETS_ESP8266_ESP8266_BOARD_UTILS_H_ */
|
||||
91
targets/esp8266/espmissingincludes.h
Normal file
91
targets/esp8266/espmissingincludes.h
Normal file
@ -0,0 +1,91 @@
|
||||
#ifndef ESPMISSINGINCLUDES_H
|
||||
#define ESPMISSINGINCLUDES_H
|
||||
|
||||
#include <user_interface.h>
|
||||
#include <eagle_soc.h>
|
||||
|
||||
//Missing function prototypes in include folders. Gcc will warn on these if we don't define 'em anywhere.
|
||||
//MOST OF THESE ARE GUESSED! but they seem to work and shut up the compiler.
|
||||
typedef struct espconn espconn;
|
||||
|
||||
bool wifi_station_set_hostname(char *);
|
||||
char *wifi_station_get_hostname(void);
|
||||
|
||||
int atoi(const char *nptr);
|
||||
|
||||
void ets_install_putc1(void *routine); // necessary for #define os_xxx -> ets_xxx
|
||||
void ets_isr_attach(int intr, void *handler, void *arg);
|
||||
void ets_isr_mask(unsigned intr);
|
||||
void ets_isr_unmask(unsigned intr);
|
||||
|
||||
int ets_memcmp(const void *s1, const void *s2, size_t n);
|
||||
void *ets_memcpy(void *dest, const void *src, size_t n);
|
||||
void *ets_memset(void *s, int c, size_t n);
|
||||
int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
int ets_str2macaddr(void *, void *);
|
||||
int ets_strcmp(const char *s1, const char *s2);
|
||||
char *ets_strcpy(char *dest, const char *src);
|
||||
size_t ets_strlen(const char *s);
|
||||
int ets_strncmp(const char *s1, const char *s2, int len);
|
||||
char *ets_strncpy(char *dest, const char *src, size_t n);
|
||||
char *ets_strstr(const char *haystack, const char *needle);
|
||||
|
||||
void ets_timer_arm_new(ETSTimer *a, int b, int c, int isMstimer);
|
||||
void ets_timer_disarm(ETSTimer *a);
|
||||
void ets_timer_setfn(ETSTimer *t, ETSTimerFunc *fn, void *parg);
|
||||
|
||||
void ets_update_cpu_frequency(int freqmhz);
|
||||
|
||||
#ifdef SDK_DBG
|
||||
#define DEBUG_SDK true
|
||||
#else
|
||||
#define DEBUG_SDK false
|
||||
#endif
|
||||
|
||||
int os_snprintf(char *str, size_t size, const char *format, ...) __attribute__((format(printf, 3, 4)));
|
||||
int os_printf_plus(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
#undef os_printf
|
||||
#define os_printf(format, ...) do {\
|
||||
system_set_os_print(true); \
|
||||
os_printf_plus(format, ## __VA_ARGS__); \
|
||||
system_set_os_print(DEBUG_SDK); \
|
||||
} while(0)
|
||||
|
||||
// memory allocation functions are "different" due to memory debugging functionality
|
||||
// added in SDK 1.4.0
|
||||
void vPortFree(void *ptr, char * file, int line);
|
||||
void *pvPortMalloc(size_t xWantedSize, char * file, int line);
|
||||
void *pvPortZalloc(size_t, char * file, int line);
|
||||
void *vPortMalloc(size_t xWantedSize);
|
||||
void pvPortFree(void *ptr);
|
||||
void *pvPortRealloc(void *pv, size_t size, char * file, int line);
|
||||
|
||||
void uart_div_modify(int no, unsigned int freq);
|
||||
uint32 system_get_time();
|
||||
int rand(void);
|
||||
void ets_bzero(void *s, size_t n);
|
||||
void ets_delay_us(int ms);
|
||||
|
||||
// disappeared in SDK 1.1.0:
|
||||
#define os_timer_done ets_timer_done
|
||||
#define os_timer_handler_isr ets_timer_handler_isr
|
||||
#define os_timer_init ets_timer_init
|
||||
|
||||
// This is not missing in SDK 1.1.0 but causes a parens error
|
||||
#undef PIN_FUNC_SELECT
|
||||
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) do { \
|
||||
WRITE_PERI_REG(PIN_NAME, \
|
||||
(READ_PERI_REG(PIN_NAME) & ~(PERIPHS_IO_MUX_FUNC<<PERIPHS_IO_MUX_FUNC_S)) \
|
||||
|( (((FUNC&BIT2)<<2)|(FUNC&0x3))<<PERIPHS_IO_MUX_FUNC_S) ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
// Shortcuts for memory functions
|
||||
//#define os_malloc pvPortMalloc // defined in SDK 1.4.0 onwards
|
||||
//#define os_free vPortFree // defined in SDK 1.4.0 onwards
|
||||
//#define os_zalloc pvPortZalloc // defined in SDK 1.4.0 onwards
|
||||
//uint8 wifi_get_opmode(void); // defined in SDK 1.0.0 onwards
|
||||
//int os_random(); // defined in SDK 1.1.0 onwards
|
||||
|
||||
#endif
|
||||
561
targets/esp8266/jshardware.c
Normal file
561
targets/esp8266/jshardware.c
Normal file
@ -0,0 +1,561 @@
|
||||
#include <ets_sys.h>
|
||||
#include <osapi.h>
|
||||
#include <os_type.h>
|
||||
#include <c_types.h>
|
||||
#include <user_interface.h>
|
||||
#include <espconn.h>
|
||||
#include <gpio.h>
|
||||
#include <mem.h>
|
||||
#include <espmissingincludes.h>
|
||||
#include <driver/uart.h>
|
||||
|
||||
//#define FAKE_STDLIB
|
||||
#define _GCC_WRAP_STDINT_H
|
||||
typedef long long int64_t;
|
||||
|
||||
#include "jshardware.h"
|
||||
#include "jsutils.h"
|
||||
#include "jsparse.h"
|
||||
#include "jsinteractive.h"
|
||||
|
||||
// The maximum time that we can safely delay/block without risking a watch dog
|
||||
// timer error or other undesirable WiFi interaction. The time is measured in
|
||||
// microseconds.
|
||||
#define MAX_SLEEP_TIME_US 10000
|
||||
|
||||
/**
|
||||
* Transmit all the characters in the transmit buffer.
|
||||
*
|
||||
*/
|
||||
void esp8266_uartTransmitAll(IOEventFlags device) {
|
||||
// Get the next character to transmit. We will have reached the end when
|
||||
// the value of the character to transmit is -1.
|
||||
int c = jshGetCharToTransmit(device);
|
||||
|
||||
while (c >= 0) {
|
||||
uart_tx_one_char(0, c);
|
||||
c = jshGetCharToTransmit(device);
|
||||
} // No more characters to transmit
|
||||
} // End of esp8266_transmitAll
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
IOEventFlags pinToEVEXTI(Pin pin) {
|
||||
return (IOEventFlags) 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the ESP8266 hardware environment.
|
||||
*/
|
||||
void jshInit() {
|
||||
// A call to jshInitDevices is architected as something we have to do.
|
||||
jshInitDevices();
|
||||
} // End of jshInit
|
||||
|
||||
void jshReset() {
|
||||
// TODO
|
||||
} // End of jshReset
|
||||
|
||||
void jshKill() {
|
||||
// TODO
|
||||
} // End of jshKill
|
||||
|
||||
/**
|
||||
* Hardware idle processing.
|
||||
*/
|
||||
void jshIdle() {
|
||||
} // End of jshIdle
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int jshGetSerialNumber(unsigned char *data, int maxChars) {
|
||||
const char *code = "ESP8266";
|
||||
strncpy((char *) data, code, maxChars);
|
||||
return strlen(code);
|
||||
} // End of jshSerialNumber
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void jshInterruptOff() {
|
||||
// TODO
|
||||
} // End of jshInterruptOff
|
||||
|
||||
void jshInterruptOn() {
|
||||
// TODO
|
||||
} // End of jshInterruptOn
|
||||
|
||||
/**
|
||||
* Delay (blocking) for the supplied number of microseconds.
|
||||
* Note that for the ESP8266 we must NOT CPU block for more than
|
||||
* 10 milliseconds or else we may starve the WiFi subsystem.
|
||||
*/
|
||||
void jshDelayMicroseconds(int microsec) {
|
||||
// Get the current time
|
||||
/*
|
||||
uint32 endTime = system_get_time() + microsec;
|
||||
while ((endTime - system_get_time()) > 10000) {
|
||||
os_delay_us(10000);
|
||||
system_soft_wdt_feed();
|
||||
}
|
||||
int lastDelta = endTime - system_get_time();
|
||||
if (lastDelta > 0) {
|
||||
os_delay_us(lastDelta);
|
||||
}
|
||||
*/
|
||||
|
||||
// This is a place holder implementation. We can and must do better
|
||||
// than this. This fails because we will sleep too long. We will sleep
|
||||
// for the given number of microseconds PLUS multiple calls back to the
|
||||
// WiFi environment.
|
||||
int count = microsec / MAX_SLEEP_TIME_US;
|
||||
for (int i=0; i<count; i++) {
|
||||
os_delay_us(MAX_SLEEP_TIME_US);
|
||||
// We may have a problem here. It was my understanding that system_soft_wdt_feed() fed
|
||||
// the underlying OS but this appears not to be the case and all it does is prevent a
|
||||
// watchdog timer from firing. What that means is that we may very well loose network
|
||||
// connectivity because we are not servicing the housekeeping. This might be one of those
|
||||
// locations where we need to look at a callback or some kind of yield technology.
|
||||
system_soft_wdt_feed();
|
||||
microsec -= MAX_SLEEP_TIME_US;
|
||||
}
|
||||
assert(microsec < MAX_SLEEP_TIME_US);
|
||||
if (microsec > 0) {
|
||||
os_delay_us(microsec);
|
||||
}
|
||||
|
||||
/*
|
||||
if (0 < microsec) {
|
||||
os_delay_us(microsec);
|
||||
}
|
||||
*/
|
||||
} // End of jshDelayMicroseconds
|
||||
|
||||
|
||||
static uint8_t PERIPHS[] = {
|
||||
PERIPHS_IO_MUX_GPIO0_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_U0TXD_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_GPIO2_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_U0RXD_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_GPIO4_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_GPIO5_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_SD_CLK_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_SD_DATA0_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_SD_DATA1_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_SD_DATA2_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_SD_DATA3_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_SD_CMD_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_MTDI_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_MTCK_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_MTMS_U - PERIPHS_IO_MUX,
|
||||
PERIPHS_IO_MUX_MTDO_U - PERIPHS_IO_MUX };
|
||||
|
||||
#define FUNC_SPI 1
|
||||
#define FUNC_GPIO 3
|
||||
#define FUNC_UART 4
|
||||
|
||||
static uint8_t pinFunction(JshPinState state) {
|
||||
switch (state) {
|
||||
case JSHPINSTATE_GPIO_OUT:
|
||||
case JSHPINSTATE_GPIO_OUT_OPENDRAIN:
|
||||
case JSHPINSTATE_GPIO_IN:
|
||||
case JSHPINSTATE_GPIO_IN_PULLUP:
|
||||
case JSHPINSTATE_GPIO_IN_PULLDOWN:
|
||||
return FUNC_GPIO;
|
||||
case JSHPINSTATE_USART_OUT:
|
||||
case JSHPINSTATE_USART_IN:
|
||||
return FUNC_UART;
|
||||
case JSHPINSTATE_I2C:
|
||||
return FUNC_SPI;
|
||||
case JSHPINSTATE_AF_OUT:
|
||||
case JSHPINSTATE_AF_OUT_OPENDRAIN:
|
||||
case JSHPINSTATE_DAC_OUT:
|
||||
case JSHPINSTATE_ADC_IN:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
} // End of pinFunction
|
||||
|
||||
/**
|
||||
* \brief Set the state of the specific pin.
|
||||
*
|
||||
* The possible states are:
|
||||
*
|
||||
* JSHPINSTATE_UNDEFINED
|
||||
* JSHPINSTATE_GPIO_OUT
|
||||
* JSHPINSTATE_GPIO_OUT_OPENDRAIN
|
||||
* JSHPINSTATE_GPIO_IN
|
||||
* JSHPINSTATE_GPIO_IN_PULLUP
|
||||
* JSHPINSTATE_GPIO_IN_PULLDOWN
|
||||
* JSHPINSTATE_ADC_IN
|
||||
* JSHPINSTATE_AF_OUT
|
||||
* JSHPINSTATE_AF_OUT_OPENDRAIN
|
||||
* JSHPINSTATE_USART_IN
|
||||
* JSHPINSTATE_USART_OUT
|
||||
* JSHPINSTATE_DAC_OUT
|
||||
* JSHPINSTATE_I2C
|
||||
*/
|
||||
void jshPinSetState(Pin pin, //!< The pin to have its state changed.
|
||||
JshPinState state //!< The new desired state of the pin.
|
||||
) {
|
||||
jsiConsolePrintf("ESP8266: jshPinSetState %d, %d\n", pin, state);
|
||||
|
||||
assert(pin < 16);
|
||||
int periph = PERIPHS_IO_MUX + PERIPHS[pin];
|
||||
|
||||
// Disable the pin's pull-up.
|
||||
PIN_PULLUP_DIS(periph);
|
||||
//PIN_PULLDWN_DIS(periph);
|
||||
|
||||
uint8_t primary_func =
|
||||
pin < 6 ?
|
||||
(PERIPHS_IO_MUX_U0TXD_U == pin
|
||||
|| PERIPHS_IO_MUX_U0RXD_U == pin) ?
|
||||
FUNC_UART : FUNC_GPIO
|
||||
: 0;
|
||||
uint8_t select_func = pinFunction(state);
|
||||
PIN_FUNC_SELECT(periph, primary_func == select_func ? 0 : select_func);
|
||||
|
||||
switch (state) {
|
||||
case JSHPINSTATE_GPIO_OUT:
|
||||
case JSHPINSTATE_GPIO_OUT_OPENDRAIN:
|
||||
//case JSHPINSTATE_AF_OUT:
|
||||
//case JSHPINSTATE_AF_OUT_OPENDRAIN:
|
||||
//case JSHPINSTATE_USART_OUT:
|
||||
//case JSHPINSTATE_DAC_OUT:
|
||||
gpio_output_set(0, 1 << pin, 1 << pin, 0);
|
||||
break;
|
||||
|
||||
case JSHPINSTATE_GPIO_IN_PULLUP:
|
||||
PIN_PULLUP_EN(periph);
|
||||
//case JSHPINSTATE_GPIO_IN_PULLDOWN: if (JSHPINSTATE_GPIO_IN_PULLDOWN == pin) PIN_PULLDWN_EN(periph);
|
||||
case JSHPINSTATE_GPIO_IN:
|
||||
gpio_output_set(0, 0, 0, 1 << pin);
|
||||
break;
|
||||
|
||||
case JSHPINSTATE_ADC_IN:
|
||||
case JSHPINSTATE_USART_IN:
|
||||
case JSHPINSTATE_I2C:
|
||||
PIN_PULLUP_EN(periph);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} // End of jshPinSetState
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return the current state of the selected pin.
|
||||
* \return The current state of the selected pin.
|
||||
*/
|
||||
JshPinState jshPinGetState(Pin pin) {
|
||||
jsiConsolePrintf("ESP8266: jshPinGetState %d\n", pin);
|
||||
return JSHPINSTATE_UNDEFINED;
|
||||
} // End of jshPinGetState
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set the value of the corresponding pin.
|
||||
*/
|
||||
void jshPinSetValue(Pin pin, //!< The pin to have its value changed.
|
||||
bool value //!< The new value of the pin.
|
||||
) {
|
||||
jsiConsolePrintf("ESP8266: jshPinSetValue %d, %d\n", pin, value);
|
||||
GPIO_OUTPUT_SET(pin, value);
|
||||
} // End of jshPinSetValue
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the value of the corresponding pin.
|
||||
* \return The current value of the pin.
|
||||
*/
|
||||
bool jshPinGetValue(Pin pin //!< The pin to have its value read.
|
||||
) {
|
||||
jsiConsolePrintf("ESP8266: jshPinGetValue %d, %d\n", pin, GPIO_INPUT_GET(pin));
|
||||
return GPIO_INPUT_GET(pin);
|
||||
} // End of jshPinGetValue
|
||||
|
||||
|
||||
bool jshIsDeviceInitialised(IOEventFlags device) {
|
||||
jsiConsolePrintf("ESP8266: jshIsDeviceInitialised %d\n", device);
|
||||
return true;
|
||||
} // End of jshIsDeviceInitialised
|
||||
|
||||
bool jshIsUSBSERIALConnected() {
|
||||
jsiConsolePrintf("ESP8266: jshIsUSBSERIALConnected\n");
|
||||
return true;
|
||||
} // End of jshIsUSBSERIALConnected
|
||||
|
||||
JsSysTime jshGetTimeFromMilliseconds(JsVarFloat ms) {
|
||||
// jsiConsolePrintf("jshGetTimeFromMilliseconds %d, %f\n", (JsSysTime)(ms * 1000.0), ms);
|
||||
return (JsSysTime) (ms * 1000.0 + 0.5);
|
||||
} // End of jshGetTimeFromMilliseconds
|
||||
|
||||
/**
|
||||
* Given a time in microseconds, get us the value in milliseconds (float)
|
||||
*/
|
||||
JsVarFloat jshGetMillisecondsFromTime(JsSysTime time) {
|
||||
// jsiConsolePrintf("jshGetMillisecondsFromTime %d, %f\n", time, (JsVarFloat)time / 1000.0);
|
||||
return (JsVarFloat) time / 1000.0;
|
||||
} // End of jshGetMillisecondsFromTime
|
||||
|
||||
/**
|
||||
* Return the current time in microseconds.
|
||||
*/
|
||||
JsSysTime jshGetSystemTime() { // in us
|
||||
return system_get_time();
|
||||
} // End of jshGetSystemTime
|
||||
|
||||
|
||||
/**
|
||||
* Set the current time in microseconds.
|
||||
*/
|
||||
void jshSetSystemTime(JsSysTime time) {
|
||||
os_printf("ESP8266: jshSetSystemTime: %d\n", time);
|
||||
} // End of jshSetSystemTime
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
JsVarFloat jshPinAnalog(Pin pin) {
|
||||
jsiConsolePrintf("ESP8266: jshPinAnalog: %d\n", pin);
|
||||
return (JsVarFloat) system_adc_read();
|
||||
} // End of jshPinAnalog
|
||||
|
||||
|
||||
int jshPinAnalogFast(Pin pin) {
|
||||
jsiConsolePrintf("ESP8266: jshPinAnalogFast: %d\n", pin);
|
||||
return NAN;
|
||||
} // End of jshPinAnalogFast
|
||||
|
||||
|
||||
JshPinFunction jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq, JshAnalogOutputFlags flags) { // if freq<=0, the default is used
|
||||
jsiConsolePrintf("ESP8266: jshPinAnalogOutput: %d, %d, %d\n", pin, (int)value, (int)freq);
|
||||
//pwm_set(pin, value < 0.0f ? 0 : 255.0f < value ? 255 : (uint8_t)value);
|
||||
return 0;
|
||||
} // End of jshPinAnalogOutput
|
||||
|
||||
|
||||
void jshSetOutputValue(JshPinFunction func, int value) {
|
||||
jsiConsolePrintf("ESP8266: jshSetOutputValue %d %d\n", func, value);
|
||||
} // End of jshSetOutputValue
|
||||
|
||||
|
||||
void jshEnableWatchDog(JsVarFloat timeout) {
|
||||
jsiConsolePrintf("ESP8266: jshEnableWatchDog %0.3f\n", timeout);
|
||||
} // End of jshEnableWatchDog
|
||||
|
||||
|
||||
bool jshGetWatchedPinState(IOEventFlags device) {
|
||||
jsiConsolePrintf("ESP8266: jshGetWatchedPinState %d", device);
|
||||
return false;
|
||||
} // End of jshGetWatchedPinState
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set the value of the pin to be the value supplied and then wait for
|
||||
* a given period and set the pin value again to be the opposite.
|
||||
*/
|
||||
void jshPinPulse(Pin pin, //!< The pin to be pulsed.
|
||||
bool value, //!< The value to be pulsed into the pin.
|
||||
JsVarFloat time //!< The period in milliseconds to hold the pin.
|
||||
) {
|
||||
if (jshIsPinValid(pin)) {
|
||||
jshPinSetState(pin, JSHPINSTATE_GPIO_OUT);
|
||||
jshPinSetValue(pin, value);
|
||||
jshDelayMicroseconds(jshGetTimeFromMilliseconds(time));
|
||||
jshPinSetValue(pin, !value);
|
||||
} else
|
||||
jsError("Invalid pin!");
|
||||
} // End of jshPinPulse
|
||||
|
||||
|
||||
bool jshCanWatch(Pin pin) {
|
||||
return false;
|
||||
} // End of jshCanWatch
|
||||
|
||||
|
||||
IOEventFlags jshPinWatch(Pin pin, bool shouldWatch) {
|
||||
if (jshIsPinValid(pin)) {
|
||||
} else
|
||||
jsError("Invalid pin!");
|
||||
return EV_NONE;
|
||||
} // End of jshPinWatch
|
||||
|
||||
|
||||
JshPinFunction jshGetCurrentPinFunction(Pin pin) {
|
||||
//os_printf("jshGetCurrentPinFunction %d\n", pin);
|
||||
return JSH_NOTHING;
|
||||
} // End of jshGetCurrentPinFunction
|
||||
|
||||
|
||||
bool jshIsEventForPin(IOEvent *event, Pin pin) {
|
||||
return IOEVENTFLAGS_GETTYPE(event->flags) == pinToEVEXTI(pin);
|
||||
} // End of jshIsEventForPin
|
||||
|
||||
|
||||
void jshUSARTSetup(IOEventFlags device, JshUSARTInfo *inf) {
|
||||
} // End of jshUSARTSetup
|
||||
|
||||
|
||||
/**
|
||||
* Kick a device into action (if required). For instance we may need
|
||||
* to set up interrupts. In this ESP8266 implementation, we transmit all the
|
||||
* data that can be found associated with the device.
|
||||
*/
|
||||
void jshUSARTKick(IOEventFlags device) {
|
||||
esp8266_uartTransmitAll(device);
|
||||
} // End of jshUSARTKick
|
||||
|
||||
void jshSPISetup(IOEventFlags device, JshSPIInfo *inf) {
|
||||
} // End of jshSPISetup
|
||||
|
||||
/** Send data through the given SPI device (if data>=0), and return the result
|
||||
* of the previous send (or -1). If data<0, no data is sent and the function
|
||||
* waits for data to be returned */
|
||||
int jshSPISend(IOEventFlags device, int data) {
|
||||
return NAN;
|
||||
} // End of jshSPISend
|
||||
|
||||
/** Send 16 bit data through the given SPI device. */
|
||||
void jshSPISend16(IOEventFlags device, int data) {
|
||||
jshSPISend(device, data >> 8);
|
||||
jshSPISend(device, data & 255);
|
||||
} // End of jshSPISend16
|
||||
|
||||
/** Set whether to send 16 bits or 8 over SPI */
|
||||
void jshSPISet16(IOEventFlags device, bool is16) {
|
||||
} // End of jshSPISet16
|
||||
|
||||
/** Wait until SPI send is finished, */
|
||||
void jshSPIWait(IOEventFlags device) {
|
||||
} // End of jshSPIWait
|
||||
|
||||
void jshI2CSetup(IOEventFlags device, JshI2CInfo *inf) {
|
||||
} // End of jshI2CSetup
|
||||
|
||||
void jshI2CWrite(IOEventFlags device, unsigned char address, int nBytes,
|
||||
const unsigned char *data, bool sendStop) {
|
||||
} // End of jshI2CWrite
|
||||
|
||||
void jshI2CRead(IOEventFlags device, unsigned char address, int nBytes,
|
||||
unsigned char *data, bool sendStop) {
|
||||
} // End of jshI2CRead
|
||||
|
||||
/**
|
||||
* \brief Save what is in RAM to flash.
|
||||
* See also `jshLoadFromFlash`.
|
||||
*/
|
||||
void jshSaveToFlash() {
|
||||
os_printf("ESP8266: jshSaveToFlash\n");
|
||||
} // End of jshSaveToFlash
|
||||
|
||||
void jshLoadFromFlash() {
|
||||
os_printf("ESP8266: jshLoadFromFlash\n");
|
||||
} // End of jshLoadFromFlash
|
||||
|
||||
|
||||
bool jshFlashContainsCode() {
|
||||
os_printf("ESP8266: jshFlashContainsCode\n");
|
||||
return false;
|
||||
} // End of jshFlashContainsCode
|
||||
|
||||
|
||||
/// Enter simple sleep mode (can be woken up by interrupts). Returns true on success
|
||||
bool jshSleep(JsSysTime timeUntilWake) {
|
||||
int time = (int) timeUntilWake;
|
||||
// os_printf("jshSleep %d\n", time);
|
||||
jshDelayMicroseconds(time);
|
||||
return true;
|
||||
} // End of jshSleep
|
||||
|
||||
|
||||
void jshUtilTimerDisable() {
|
||||
os_printf("ESP8266: jshUtilTimerDisable\n");
|
||||
} // End of jshUtilTimerDisable
|
||||
|
||||
|
||||
void jshUtilTimerReschedule(JsSysTime period) {
|
||||
os_printf("ESP8266: jshUtilTimerReschedule %d\n", period);
|
||||
} // End of jshUtilTimerReschedule
|
||||
|
||||
|
||||
void jshUtilTimerStart(JsSysTime period) {
|
||||
os_printf("ESP8266: jshUtilTimerStart %d\n", period);
|
||||
} // End of jshUtilTimerStart
|
||||
|
||||
|
||||
JsVarFloat jshReadTemperature() {
|
||||
return NAN;
|
||||
} // End of jshReadTemperature
|
||||
|
||||
|
||||
JsVarFloat jshReadVRef() {
|
||||
return NAN;
|
||||
} // End of jshReadVRef
|
||||
|
||||
|
||||
unsigned int jshGetRandomNumber() {
|
||||
return rand();
|
||||
} // End of jshGetRandomNumber
|
||||
|
||||
|
||||
/**
|
||||
* \brief Read data from flash memory into the buffer.
|
||||
*
|
||||
*/
|
||||
void jshFlashRead(
|
||||
void *buf, //!< buffer to read into
|
||||
uint32_t addr, //!< Flash address to read from
|
||||
uint32_t len //!< Length of data to read
|
||||
) {
|
||||
os_printf("ESP8266: jshFlashRead: buf=0x%x for len=%d from flash addr=0x%x\n", buf, len, addr);
|
||||
} // End of jshFlashRead
|
||||
|
||||
|
||||
/**
|
||||
* \brief Write data to flash memory from the buffer.
|
||||
*/
|
||||
void jshFlashWrite(
|
||||
void *buf, //!< Buffer to write from
|
||||
uint32_t addr, //!< Flash address to write into
|
||||
uint32_t len //!< Length of data to write
|
||||
) {
|
||||
os_printf("ESP8266: jshFlashWrite: buf=0x%x for len=%d into flash addr=0x%x\n", buf, len, addr);
|
||||
} // End of jshFlashWrite
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return start address and size of the flash page the given address resides in. Returns false if no page.
|
||||
*/
|
||||
bool jshFlashGetPage(
|
||||
uint32_t addr, //!<
|
||||
uint32_t *startAddr, //!<
|
||||
uint32_t *pageSize //!<
|
||||
) {
|
||||
os_printf("ESP8266: jshFlashGetPage: addr=0x%x, startAddr=0x%x, pageSize=%d\n", addr, startAddr, pageSize);
|
||||
return false;
|
||||
} // End of jshFlashGetPage
|
||||
|
||||
|
||||
/**
|
||||
* \brief Erase the flash page containing the address.
|
||||
*/
|
||||
void jshFlashErasePage(
|
||||
uint32_t addr //!<
|
||||
) {
|
||||
os_printf("ESP8266: jshFlashErasePage: addr=0x%x\n", addr);
|
||||
} // End of jshFlashErasePage
|
||||
|
||||
|
||||
/** Set whether to use the receive interrupt or not */
|
||||
void jshSPISetReceive(IOEventFlags device, bool isReceive) {
|
||||
} // End of jshSPISetReceive
|
||||
|
||||
|
||||
/**
|
||||
* Callback for end of runtime. This should never be called and has been
|
||||
* added to satisfy the linker.
|
||||
*/
|
||||
void _exit(int status) {
|
||||
} // End of _exit
|
||||
// End of file
|
||||
25
targets/esp8266/telnet.h
Normal file
25
targets/esp8266/telnet.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* This file is part of Espruino/ESP8266, a JavaScript interpreter for ESP8266
|
||||
*
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef USER_TELNET_H_
|
||||
#define USER_TELNET_H_
|
||||
|
||||
/**
|
||||
* Register a telnet serever listener on port 23 to handle incoming telnet client
|
||||
* connections. The parameter called pLineCB is a pointer to a callback function
|
||||
* that should be called when we have received a link of input.
|
||||
*/
|
||||
void telnet_startListening(void (*lineCB)(char *arg));
|
||||
|
||||
/**
|
||||
* Send the string passed as a parameter to the telnet client.
|
||||
*/
|
||||
void telnet_send(char *text);
|
||||
|
||||
#endif /* USER_TELNET_H_ */
|
||||
94
targets/esp8266/telnet_client.c
Normal file
94
targets/esp8266/telnet_client.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of Espruino/ESP8266, a JavaScript interpreter for ESP8266
|
||||
*
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
//#include "espmissingincludes.h"
|
||||
#include <ets_sys.h>
|
||||
#include <osapi.h>
|
||||
#include <os_type.h>
|
||||
#include <user_interface.h>
|
||||
#include <espconn.h>
|
||||
#include <mem.h>
|
||||
#include <telnet.h>
|
||||
|
||||
#define MAXLINE 200
|
||||
|
||||
static char line[MAXLINE];
|
||||
static struct espconn conn1;
|
||||
static esp_tcp tcp1;
|
||||
static bool discard;
|
||||
static void (*lineCB)(char *);
|
||||
static struct espconn *pTelnetClientConn;
|
||||
|
||||
/**
|
||||
* Callback invoked when a new TCP/IP connection has been formed.
|
||||
* o arg - This is a pointer to the struct espconn that reflects this entry.
|
||||
*/
|
||||
static void connectCB(void *arg) {
|
||||
struct espconn *pConn = (struct espconn *)arg;
|
||||
|
||||
// By default, an ESP TCP connection times out after 10 seconds
|
||||
// Change to the max value.
|
||||
espconn_regist_time(pConn, 7200, 1);
|
||||
|
||||
os_printf("Connect cb!!\n");
|
||||
strcpy(line, "");
|
||||
discard = false;
|
||||
pTelnetClientConn = pConn;
|
||||
} // End of connectCB
|
||||
|
||||
static void disconnectCB(void *arg) {
|
||||
os_printf("Disconnect cb!!\n");
|
||||
} // End of disconnectCB
|
||||
|
||||
|
||||
static void receiveCB(void *arg, char *pData, unsigned short len) {
|
||||
//os_printf("Receive cb!! len=%d\n", len);
|
||||
if (strlen(line) + len >= MAXLINE) {
|
||||
discard = true;
|
||||
strcpy(line, "");
|
||||
}
|
||||
strncat(line, pData, len);
|
||||
if (strstr(line, "\r\n") != NULL) {
|
||||
if (discard) {
|
||||
os_printf("Discarded ... line too long");
|
||||
discard = false;
|
||||
} else {
|
||||
//os_printf("Found: %s", line);
|
||||
(*lineCB)(line);
|
||||
}
|
||||
strcpy(line, "");
|
||||
} else {
|
||||
//os_printf("Not found, current='%s'\n", line);
|
||||
}
|
||||
} // End of receiveCB
|
||||
|
||||
/**
|
||||
* Register a telnet serever listener on port 23 to handle incoming telnet client
|
||||
* connections. The parameter called pLineCB is a pointer to a callback function
|
||||
* that should be called when we have received a link of input.
|
||||
*/
|
||||
void telnet_startListening(void (*plineCB)(char *)) {
|
||||
lineCB= plineCB;
|
||||
tcp1.local_port = 23;
|
||||
conn1.type = ESPCONN_TCP;
|
||||
conn1.state = ESPCONN_NONE;
|
||||
conn1.proto.tcp = &tcp1;
|
||||
espconn_regist_connectcb(&conn1, connectCB);
|
||||
espconn_regist_disconcb(&conn1, disconnectCB);
|
||||
espconn_regist_recvcb(&conn1, receiveCB);
|
||||
espconn_accept(&conn1);
|
||||
os_printf("Now listening for telnet client connection ...\n");
|
||||
} // End of telnet_startListening
|
||||
|
||||
/**
|
||||
* Send the string passed as a parameter to the telnet client.
|
||||
*/
|
||||
void telnet_send(char *text) {
|
||||
espconn_sent(pTelnetClientConn, (uint8_t *)text, strlen(text));
|
||||
} // End of telnet_send
|
||||
// End of file
|
||||
821
targets/esp8266/uart.c
Normal file
821
targets/esp8266/uart.c
Normal file
@ -0,0 +1,821 @@
|
||||
/*
|
||||
* File : uart.c
|
||||
* Copyright (C) 2013 - 2016, Espressif Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of version 3 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "driver/uart.h"
|
||||
#include "osapi.h"
|
||||
#include "driver/uart_register.h"
|
||||
#include "mem.h"
|
||||
#include "os_type.h"
|
||||
#include "espmissingincludes.h"
|
||||
|
||||
// UartDev is defined and initialized in rom code.
|
||||
extern UartDevice UartDev;
|
||||
|
||||
LOCAL struct UartBuffer* pTxBuffer = NULL;
|
||||
LOCAL struct UartBuffer* pRxBuffer = NULL;
|
||||
|
||||
#define MAX_RX_BUFFER 500
|
||||
static char rxBuffer[MAX_RX_BUFFER];
|
||||
static int rxBufferLen = 0;
|
||||
|
||||
int getRXBuffer(char *pBuffer, int bufferLen) {
|
||||
if (rxBufferLen > bufferLen) {
|
||||
memcpy(pBuffer,rxBuffer, bufferLen);
|
||||
memcpy(rxBuffer, rxBuffer+bufferLen, rxBufferLen-bufferLen);
|
||||
rxBufferLen = rxBufferLen - bufferLen;
|
||||
return bufferLen;
|
||||
}
|
||||
int sizeReturned = rxBufferLen;
|
||||
memcpy(pBuffer, rxBuffer, rxBufferLen);
|
||||
rxBufferLen = 0;
|
||||
return sizeReturned;
|
||||
} // End of getRXBuffer
|
||||
|
||||
/*uart demo with a system task, to output what uart receives*/
|
||||
/*this is a example to process uart data from task,please change the priority to fit your application task if exists*/
|
||||
/*it might conflict with your task, if so,please arrange the priority of different task, or combine it to a different event in the same task. */
|
||||
#define uart_recvTaskPrio 2
|
||||
#define uart_recvTaskQueueLen 10
|
||||
os_event_t uart_recvTaskQueue[uart_recvTaskQueueLen];
|
||||
|
||||
#define DBG
|
||||
#define DBG1 uart1_sendStr_no_wait
|
||||
#define DBG2 os_printf
|
||||
|
||||
|
||||
LOCAL void uart0_rx_intr_handler(void *para);
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart_config
|
||||
* Description : Internal used function
|
||||
* UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled
|
||||
* UART1 just used for debug output
|
||||
* Parameters : uart_no, use UART0 or UART1 defined ahead
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
LOCAL void ICACHE_FLASH_ATTR
|
||||
uart_config(uint8 uart_no)
|
||||
{
|
||||
if (uart_no == UART1){
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
|
||||
}else{
|
||||
/* rcv_buff size if 0x100 */
|
||||
ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff));
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
|
||||
#if UART_HW_RTS
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); //HW FLOW CONTROL RTS PIN
|
||||
#endif
|
||||
#if UART_HW_CTS
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_U0CTS); //HW FLOW CONTROL CTS PIN
|
||||
#endif
|
||||
}
|
||||
uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));//SET BAUDRATE
|
||||
|
||||
WRITE_PERI_REG(UART_CONF0(uart_no), ((UartDev.exist_parity & UART_PARITY_EN_M) << UART_PARITY_EN_S) //SET BIT AND PARITY MODE
|
||||
| ((UartDev.parity & UART_PARITY_M) <<UART_PARITY_S )
|
||||
| ((UartDev.stop_bits & UART_STOP_BIT_NUM) << UART_STOP_BIT_NUM_S)
|
||||
| ((UartDev.data_bits & UART_BIT_NUM) << UART_BIT_NUM_S));
|
||||
|
||||
//clear rx and tx fifo,not ready
|
||||
SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); //RESET FIFO
|
||||
CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
|
||||
|
||||
if (uart_no == UART0){
|
||||
//set rx fifo trigger
|
||||
WRITE_PERI_REG(UART_CONF1(uart_no),
|
||||
((100 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |
|
||||
#if UART_HW_RTS
|
||||
((110 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) |
|
||||
UART_RX_FLOW_EN | //enbale rx flow control
|
||||
#endif
|
||||
(0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S |
|
||||
UART_RX_TOUT_EN|
|
||||
((0x10 & UART_TXFIFO_EMPTY_THRHD)<<UART_TXFIFO_EMPTY_THRHD_S));//wjl
|
||||
#if UART_HW_CTS
|
||||
SET_PERI_REG_MASK( UART_CONF0(uart_no),UART_TX_FLOW_EN); //add this sentense to add a tx flow control via MTCK( CTS )
|
||||
#endif
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_TOUT_INT_ENA |UART_FRM_ERR_INT_ENA);
|
||||
}else{
|
||||
WRITE_PERI_REG(UART_CONF1(uart_no),((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S));//TrigLvl default val == 1
|
||||
}
|
||||
//clear all interrupt
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff);
|
||||
//enable rx_interrupt
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_OVF_INT_ENA);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart1_tx_one_char
|
||||
* Description : Internal used function
|
||||
* Use uart1 interface to transfer one char
|
||||
* Parameters : uint8 TxChar - character to tx
|
||||
* Returns : OK
|
||||
*******************************************************************************/
|
||||
STATUS uart_tx_one_char(uint8 uart, uint8 TxChar)
|
||||
{
|
||||
while (true){
|
||||
uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S);
|
||||
if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart1_write_char
|
||||
* Description : Internal used function
|
||||
* Do some special deal while tx char is '\r' or '\n'
|
||||
* Parameters : char c - character to tx
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
LOCAL void ICACHE_FLASH_ATTR
|
||||
uart1_write_char(char c)
|
||||
{
|
||||
if (c == '\n'){
|
||||
uart_tx_one_char(UART1, '\r');
|
||||
uart_tx_one_char(UART1, '\n');
|
||||
}else if (c == '\r'){
|
||||
|
||||
}else{
|
||||
uart_tx_one_char(UART1, c);
|
||||
}
|
||||
}
|
||||
|
||||
//os_printf output to fifo or to the tx buffer
|
||||
LOCAL void ICACHE_FLASH_ATTR
|
||||
uart0_write_char_no_wait(char c)
|
||||
{
|
||||
#if UART_BUFF_EN //send to uart0 fifo but do not wait
|
||||
uint8 chr;
|
||||
if (c == '\n'){
|
||||
chr = '\r';
|
||||
tx_buff_enq(&chr, 1);
|
||||
chr = '\n';
|
||||
tx_buff_enq(&chr, 1);
|
||||
}else if (c == '\r'){
|
||||
|
||||
}else{
|
||||
tx_buff_enq(&c,1);
|
||||
}
|
||||
#else //send to uart tx buffer
|
||||
if (c == '\n'){
|
||||
uart_tx_one_char_no_wait(UART0, '\r');
|
||||
uart_tx_one_char_no_wait(UART0, '\n');
|
||||
}else if (c == '\r'){
|
||||
|
||||
}
|
||||
else{
|
||||
uart_tx_one_char_no_wait(UART0, c);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart0_tx_buffer
|
||||
* Description : use uart0 to transfer buffer
|
||||
* Parameters : uint8 *buf - point to send buffer
|
||||
* uint16 len - buffer len
|
||||
* Returns :
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
uart0_tx_buffer(uint8 *buf, uint16 len)
|
||||
{
|
||||
uint16 i;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
uart_tx_one_char(UART0, buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart0_sendStr
|
||||
* Description : use uart0 to transfer buffer
|
||||
* Parameters : uint8 *buf - point to send buffer
|
||||
* uint16 len - buffer len
|
||||
* Returns :
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
uart0_sendStr(const char *str)
|
||||
{
|
||||
while(*str){
|
||||
uart_tx_one_char(UART0, *str++);
|
||||
}
|
||||
}
|
||||
void at_port_print(const char *str) __attribute__((alias("uart0_sendStr")));
|
||||
/******************************************************************************
|
||||
* FunctionName : uart0_rx_intr_handler
|
||||
* Description : Internal used function
|
||||
* UART0 interrupt handler, add self handle code inside
|
||||
* Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
LOCAL void
|
||||
uart0_rx_intr_handler(void *para)
|
||||
{
|
||||
/* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
|
||||
* uart1 and uart0 respectively
|
||||
*/
|
||||
uint8 RcvChar;
|
||||
uint8 uart_no = UART0;//UartDev.buff_uart_no;
|
||||
uint8 fifo_len = 0;
|
||||
uint8 buf_idx = 0;
|
||||
uint8 temp,cnt;
|
||||
//RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para;
|
||||
|
||||
/*ATTENTION:*/
|
||||
/*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/
|
||||
/*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */
|
||||
/*IF NOT , POST AN EVENT AND PROCESS IN SYSTEM TASK */
|
||||
if(UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)){
|
||||
DBG1("FRM_ERR\r\n");
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);
|
||||
}else if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)){
|
||||
DBG("f");
|
||||
uart_rx_intr_disable(UART0);
|
||||
WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR);
|
||||
system_os_post(uart_recvTaskPrio, 0, 0);
|
||||
}else if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)){
|
||||
DBG("t");
|
||||
uart_rx_intr_disable(UART0);
|
||||
WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR);
|
||||
system_os_post(uart_recvTaskPrio, 0, 0);
|
||||
}else if(UART_TXFIFO_EMPTY_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_TXFIFO_EMPTY_INT_ST)){
|
||||
DBG("e");
|
||||
/* to output uart data from uart buffer directly in empty interrupt handler*/
|
||||
/*instead of processing in system event, in order not to wait for current task/function to quit */
|
||||
/*ATTENTION:*/
|
||||
/*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/
|
||||
/*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */
|
||||
CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
|
||||
#if UART_BUFF_EN
|
||||
tx_start_uart_buffer(UART0);
|
||||
#endif
|
||||
//system_os_post(uart_recvTaskPrio, 1, 0);
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR);
|
||||
|
||||
}else if(UART_RXFIFO_OVF_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_OVF_INT_ST)){
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_OVF_INT_CLR);
|
||||
DBG1("RX OVF!!\r\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart_init
|
||||
* Description : user interface for init uart
|
||||
* Parameters : UartBautRate uart0_br - uart0 bautrate
|
||||
* UartBautRate uart1_br - uart1 bautrate
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
#if UART_SELFTEST&UART_BUFF_EN
|
||||
os_timer_t buff_timer_t;
|
||||
void ICACHE_FLASH_ATTR
|
||||
uart_test_rx()
|
||||
{
|
||||
uint8 uart_buf[128]={0};
|
||||
uint16 len = 0;
|
||||
len = rx_buff_deq(uart_buf, 128 );
|
||||
tx_buff_enq(uart_buf,len);
|
||||
}
|
||||
#endif
|
||||
|
||||
LOCAL void ICACHE_FLASH_ATTR ///////
|
||||
uart_recvTask(os_event_t *events)
|
||||
{
|
||||
if(events->sig == 0){
|
||||
#if UART_BUFF_EN
|
||||
Uart_rx_buff_enq();
|
||||
#else
|
||||
uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;
|
||||
uint8 d_tmp = 0;
|
||||
uint8 idx=0;
|
||||
for(idx=0;idx<fifo_len;idx++) {
|
||||
d_tmp = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
|
||||
// Uncomment the following line to local echo
|
||||
//uart_tx_one_char(UART0, d_tmp);
|
||||
if (rxBufferLen < MAX_RX_BUFFER) {
|
||||
rxBuffer[rxBufferLen] = d_tmp;
|
||||
rxBufferLen++;
|
||||
}
|
||||
}
|
||||
if (fifo_len > 0) {
|
||||
system_os_post(1, 2, 0);
|
||||
}
|
||||
WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR|UART_RXFIFO_TOUT_INT_CLR);
|
||||
uart_rx_intr_enable(UART0);
|
||||
#endif
|
||||
}else if(events->sig == 1){
|
||||
#if UART_BUFF_EN
|
||||
//already move uart buffer output to uart empty interrupt
|
||||
//tx_start_uart_buffer(UART0);
|
||||
#else
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
uart_init(UartBautRate uart0_br, UartBautRate uart1_br)
|
||||
{
|
||||
/*this is a example to process uart data from task,please change the priority to fit your application task if exists*/
|
||||
system_os_task(uart_recvTask, uart_recvTaskPrio, uart_recvTaskQueue, uart_recvTaskQueueLen); //demo with a task to process the uart data
|
||||
|
||||
UartDev.baut_rate = uart0_br;
|
||||
uart_config(UART0);
|
||||
UartDev.baut_rate = uart1_br;
|
||||
uart_config(UART1);
|
||||
ETS_UART_INTR_ENABLE();
|
||||
|
||||
#if UART_BUFF_EN
|
||||
pTxBuffer = Uart_Buf_Init(UART_TX_BUFFER_SIZE);
|
||||
pRxBuffer = Uart_Buf_Init(UART_RX_BUFFER_SIZE);
|
||||
#endif
|
||||
|
||||
|
||||
/*option 1: use default print, output from uart0 , will wait some time if fifo is full */
|
||||
//do nothing...
|
||||
|
||||
/*option 2: output from uart1,uart1 output will not wait , just for output debug info */
|
||||
/*os_printf output uart data via uart1(GPIO2)*/
|
||||
//os_install_putc1((void *)uart1_write_char); //use this one to output debug information via uart1 //
|
||||
|
||||
/*option 3: output from uart0 will skip current byte if fifo is full now... */
|
||||
/*see uart0_write_char_no_wait:you can output via a buffer or output directly */
|
||||
/*os_printf output uart data via uart0 or uart buffer*/
|
||||
//os_install_putc1((void *)uart0_write_char_no_wait); //use this to print via uart0
|
||||
|
||||
#if UART_SELFTEST&UART_BUFF_EN
|
||||
os_timer_disarm(&buff_timer_t);
|
||||
os_timer_setfn(&buff_timer_t, uart_test_rx , NULL); //a demo to process the data in uart rx buffer
|
||||
os_timer_arm(&buff_timer_t,10,1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
uart_reattach()
|
||||
{
|
||||
uart_init(BIT_RATE_115200, BIT_RATE_115200);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart_tx_one_char_no_wait
|
||||
* Description : uart tx a single char without waiting for fifo
|
||||
* Parameters : uint8 uart - uart port
|
||||
* uint8 TxChar - char to tx
|
||||
* Returns : STATUS
|
||||
*******************************************************************************/
|
||||
STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar)
|
||||
{
|
||||
uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(uart))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT);
|
||||
if (fifo_cnt < 126) {
|
||||
WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
STATUS uart0_tx_one_char_no_wait(uint8 TxChar)
|
||||
{
|
||||
uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(UART0))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT);
|
||||
if (fifo_cnt < 126) {
|
||||
WRITE_PERI_REG(UART_FIFO(UART0) , TxChar);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart1_sendStr_no_wait
|
||||
* Description : uart tx a string without waiting for every char, used for print debug info which can be lost
|
||||
* Parameters : const char *str - string to be sent
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void uart1_sendStr_no_wait(const char *str)
|
||||
{
|
||||
while(*str){
|
||||
uart_tx_one_char_no_wait(UART1, *str++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UART_BUFF_EN
|
||||
/******************************************************************************
|
||||
* FunctionName : Uart_Buf_Init
|
||||
* Description : tx buffer enqueue: fill a first linked buffer
|
||||
* Parameters : char *pdata - data point to be enqueue
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
struct UartBuffer* ICACHE_FLASH_ATTR
|
||||
Uart_Buf_Init(uint32 buf_size)
|
||||
{
|
||||
uint32 heap_size = system_get_free_heap_size();
|
||||
if(heap_size <=buf_size){
|
||||
DBG1("no buf for uart\n\r");
|
||||
return NULL;
|
||||
}else{
|
||||
DBG("test heap size: %d\n\r",heap_size);
|
||||
struct UartBuffer* pBuff = (struct UartBuffer* )os_malloc(sizeof(struct UartBuffer));
|
||||
pBuff->UartBuffSize = buf_size;
|
||||
pBuff->pUartBuff = (uint8*)os_malloc(pBuff->UartBuffSize);
|
||||
pBuff->pInPos = pBuff->pUartBuff;
|
||||
pBuff->pOutPos = pBuff->pUartBuff;
|
||||
pBuff->Space = pBuff->UartBuffSize;
|
||||
pBuff->BuffState = OK;
|
||||
pBuff->nextBuff = NULL;
|
||||
pBuff->TcpControl = RUN;
|
||||
return pBuff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//copy uart buffer
|
||||
LOCAL void Uart_Buf_Cpy(struct UartBuffer* pCur, char* pdata , uint16 data_len)
|
||||
{
|
||||
if(data_len == 0) return ;
|
||||
|
||||
uint16 tail_len = pCur->pUartBuff + pCur->UartBuffSize - pCur->pInPos ;
|
||||
if(tail_len >= data_len){ //do not need to loop back the queue
|
||||
os_memcpy(pCur->pInPos , pdata , data_len );
|
||||
pCur->pInPos += ( data_len );
|
||||
pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize );
|
||||
pCur->Space -=data_len;
|
||||
}else{
|
||||
os_memcpy(pCur->pInPos, pdata, tail_len);
|
||||
pCur->pInPos += ( tail_len );
|
||||
pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize );
|
||||
pCur->Space -=tail_len;
|
||||
os_memcpy(pCur->pInPos, pdata+tail_len , data_len-tail_len);
|
||||
pCur->pInPos += ( data_len-tail_len );
|
||||
pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize );
|
||||
pCur->Space -=( data_len-tail_len);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart_buf_free
|
||||
* Description : deinit of the tx buffer
|
||||
* Parameters : struct UartBuffer* pTxBuff - tx buffer struct pointer
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
uart_buf_free(struct UartBuffer* pBuff)
|
||||
{
|
||||
os_free(pBuff->pUartBuff);
|
||||
os_free(pBuff);
|
||||
}
|
||||
|
||||
|
||||
//rx buffer dequeue
|
||||
uint16 ICACHE_FLASH_ATTR
|
||||
rx_buff_deq(char* pdata, uint16 data_len )
|
||||
{
|
||||
uint16 buf_len = (pRxBuffer->UartBuffSize- pRxBuffer->Space);
|
||||
uint16 tail_len = pRxBuffer->pUartBuff + pRxBuffer->UartBuffSize - pRxBuffer->pOutPos ;
|
||||
uint16 len_tmp = 0;
|
||||
len_tmp = ((data_len > buf_len)?buf_len:data_len);
|
||||
if(pRxBuffer->pOutPos <= pRxBuffer->pInPos){
|
||||
os_memcpy(pdata, pRxBuffer->pOutPos,len_tmp);
|
||||
pRxBuffer->pOutPos+= len_tmp;
|
||||
pRxBuffer->Space += len_tmp;
|
||||
}else{
|
||||
if(len_tmp>tail_len){
|
||||
os_memcpy(pdata, pRxBuffer->pOutPos, tail_len);
|
||||
pRxBuffer->pOutPos += tail_len;
|
||||
pRxBuffer->pOutPos = (pRxBuffer->pUartBuff + (pRxBuffer->pOutPos- pRxBuffer->pUartBuff) % pRxBuffer->UartBuffSize );
|
||||
pRxBuffer->Space += tail_len;
|
||||
|
||||
os_memcpy(pdata+tail_len , pRxBuffer->pOutPos, len_tmp-tail_len);
|
||||
pRxBuffer->pOutPos+= ( len_tmp-tail_len );
|
||||
pRxBuffer->pOutPos= (pRxBuffer->pUartBuff + (pRxBuffer->pOutPos- pRxBuffer->pUartBuff) % pRxBuffer->UartBuffSize );
|
||||
pRxBuffer->Space +=( len_tmp-tail_len);
|
||||
}else{
|
||||
//os_printf("case 3 in rx deq\n\r");
|
||||
os_memcpy(pdata, pRxBuffer->pOutPos, len_tmp);
|
||||
pRxBuffer->pOutPos += len_tmp;
|
||||
pRxBuffer->pOutPos = (pRxBuffer->pUartBuff + (pRxBuffer->pOutPos- pRxBuffer->pUartBuff) % pRxBuffer->UartBuffSize );
|
||||
pRxBuffer->Space += len_tmp;
|
||||
}
|
||||
}
|
||||
if(pRxBuffer->Space >= UART_FIFO_LEN){
|
||||
uart_rx_intr_enable(UART0);
|
||||
}
|
||||
return len_tmp;
|
||||
}
|
||||
|
||||
|
||||
//move data from uart fifo to rx buffer
|
||||
void Uart_rx_buff_enq()
|
||||
{
|
||||
uint8 fifo_len,buf_idx;
|
||||
uint8 fifo_data;
|
||||
#if 1
|
||||
fifo_len = (READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;
|
||||
if(fifo_len >= pRxBuffer->Space){
|
||||
os_printf("buf full!!!\n\r");
|
||||
}else{
|
||||
buf_idx=0;
|
||||
while(buf_idx < fifo_len){
|
||||
buf_idx++;
|
||||
fifo_data = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
|
||||
*(pRxBuffer->pInPos++) = fifo_data;
|
||||
if(pRxBuffer->pInPos == (pRxBuffer->pUartBuff + pRxBuffer->UartBuffSize)){
|
||||
pRxBuffer->pInPos = pRxBuffer->pUartBuff;
|
||||
}
|
||||
}
|
||||
pRxBuffer->Space -= fifo_len ;
|
||||
if(pRxBuffer->Space >= UART_FIFO_LEN){
|
||||
//os_printf("after rx enq buf enough\n\r");
|
||||
uart_rx_intr_enable(UART0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//fill the uart tx buffer
|
||||
void ICACHE_FLASH_ATTR
|
||||
tx_buff_enq(char* pdata, uint16 data_len )
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
|
||||
|
||||
if(pTxBuffer == NULL){
|
||||
DBG1("\n\rnull, create buffer struct\n\r");
|
||||
pTxBuffer = Uart_Buf_Init(UART_TX_BUFFER_SIZE);
|
||||
if(pTxBuffer!= NULL){
|
||||
Uart_Buf_Cpy(pTxBuffer , pdata, data_len );
|
||||
}else{
|
||||
DBG1("uart tx MALLOC no buf \n\r");
|
||||
}
|
||||
}else{
|
||||
if(data_len <= pTxBuffer->Space){
|
||||
Uart_Buf_Cpy(pTxBuffer , pdata, data_len);
|
||||
}else{
|
||||
DBG1("UART TX BUF FULL!!!!\n\r");
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if(pTxBuffer->Space <= URAT_TX_LOWER_SIZE){
|
||||
set_tcp_block();
|
||||
}
|
||||
#endif
|
||||
SET_PERI_REG_MASK(UART_CONF1(UART0), (UART_TX_EMPTY_THRESH_VAL & UART_TXFIFO_EMPTY_THRHD)<<UART_TXFIFO_EMPTY_THRHD_S);
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------
|
||||
LOCAL void tx_fifo_insert(struct UartBuffer* pTxBuff, uint8 data_len, uint8 uart_no)
|
||||
{
|
||||
uint8 i;
|
||||
for(i = 0; i<data_len;i++){
|
||||
WRITE_PERI_REG(UART_FIFO(uart_no) , *(pTxBuff->pOutPos++));
|
||||
if(pTxBuff->pOutPos == (pTxBuff->pUartBuff + pTxBuff->UartBuffSize)){
|
||||
pTxBuff->pOutPos = pTxBuff->pUartBuff;
|
||||
}
|
||||
}
|
||||
pTxBuff->pOutPos = (pTxBuff->pUartBuff + (pTxBuff->pOutPos - pTxBuff->pUartBuff) % pTxBuff->UartBuffSize );
|
||||
pTxBuff->Space += data_len;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : tx_start_uart_buffer
|
||||
* Description : get data from the tx buffer and fill the uart tx fifo, co-work with the uart fifo empty interrupt
|
||||
* Parameters : uint8 uart_no - uart port num
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void tx_start_uart_buffer(uint8 uart_no)
|
||||
{
|
||||
uint8 tx_fifo_len = (READ_PERI_REG(UART_STATUS(uart_no))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT;
|
||||
uint8 fifo_remain = UART_FIFO_LEN - tx_fifo_len ;
|
||||
uint8 len_tmp;
|
||||
uint16 tail_ptx_len,head_ptx_len,data_len;
|
||||
//struct UartBuffer* pTxBuff = *get_buff_prt();
|
||||
|
||||
if(pTxBuffer){
|
||||
data_len = (pTxBuffer->UartBuffSize - pTxBuffer->Space);
|
||||
if(data_len > fifo_remain){
|
||||
len_tmp = fifo_remain;
|
||||
tx_fifo_insert( pTxBuffer,len_tmp,uart_no);
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
|
||||
}else{
|
||||
len_tmp = data_len;
|
||||
tx_fifo_insert( pTxBuffer,len_tmp,uart_no);
|
||||
}
|
||||
}else{
|
||||
DBG1("pTxBuff null \n\r");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void uart_rx_intr_disable(uint8 uart_no)
|
||||
{
|
||||
#if 1
|
||||
CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
|
||||
#else
|
||||
ETS_UART_INTR_DISABLE();
|
||||
#endif
|
||||
}
|
||||
|
||||
void uart_rx_intr_enable(uint8 uart_no)
|
||||
{
|
||||
#if 1
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
|
||||
#else
|
||||
ETS_UART_INTR_ENABLE();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//========================================================
|
||||
LOCAL void
|
||||
uart0_write_char(char c)
|
||||
{
|
||||
if (c == '\n') {
|
||||
uart_tx_one_char(UART0, '\r');
|
||||
uart_tx_one_char(UART0, '\n');
|
||||
} else if (c == '\r') {
|
||||
} else {
|
||||
uart_tx_one_char(UART0, c);
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len)
|
||||
{
|
||||
SET_PERI_REG_BITS(UART_CONF0(uart_no),UART_BIT_NUM,len,UART_BIT_NUM_S);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num)
|
||||
{
|
||||
SET_PERI_REG_BITS(UART_CONF0(uart_no),UART_STOP_BIT_NUM,bit_num,UART_STOP_BIT_NUM_S);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_LINE_INV_MASK);
|
||||
SET_PERI_REG_MASK(UART_CONF0(uart_no), inverse_mask);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_SetParity(uint8 uart_no, UartParityMode Parity_mode)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY |UART_PARITY_EN);
|
||||
if(Parity_mode==NONE_BITS){
|
||||
}else{
|
||||
SET_PERI_REG_MASK(UART_CONF0(uart_no), Parity_mode|UART_PARITY_EN);
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_SetBaudrate(uint8 uart_no,uint32 baud_rate)
|
||||
{
|
||||
uart_div_modify(uart_no, UART_CLK_FREQ /baud_rate);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh)
|
||||
{
|
||||
if(flow_ctrl&USART_HardwareFlowControl_RTS){
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS);
|
||||
SET_PERI_REG_BITS(UART_CONF1(uart_no),UART_RX_FLOW_THRHD,rx_thresh,UART_RX_FLOW_THRHD_S);
|
||||
SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN);
|
||||
}else{
|
||||
CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN);
|
||||
}
|
||||
if(flow_ctrl&USART_HardwareFlowControl_CTS){
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS);
|
||||
SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN);
|
||||
}else{
|
||||
CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN);
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us) //do not use if tx flow control enabled
|
||||
{
|
||||
uint32 t_s = system_get_time();
|
||||
while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)){
|
||||
|
||||
if(( system_get_time() - t_s )> time_out_us){
|
||||
break;
|
||||
}
|
||||
WRITE_PERI_REG(0X60000914, 0X73);//WTD
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ICACHE_FLASH_ATTR
|
||||
UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us)
|
||||
{
|
||||
uint32 t_start = system_get_time();
|
||||
uint8 tx_fifo_len;
|
||||
uint32 tx_buff_len;
|
||||
while(1){
|
||||
tx_fifo_len =( (READ_PERI_REG(UART_STATUS(uart_no))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT);
|
||||
if(pTxBuffer){
|
||||
tx_buff_len = ((pTxBuffer->UartBuffSize)-(pTxBuffer->Space));
|
||||
}else{
|
||||
tx_buff_len = 0;
|
||||
}
|
||||
|
||||
if( tx_fifo_len==0 && tx_buff_len==0){
|
||||
return TRUE;
|
||||
}
|
||||
if( system_get_time() - t_start > time_out_us){
|
||||
return FALSE;
|
||||
}
|
||||
WRITE_PERI_REG(0X60000914, 0X73);//WTD
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_ResetFifo(uint8 uart_no)
|
||||
{
|
||||
SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
|
||||
CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask)
|
||||
{
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), clr_mask);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_SetIntrEna(uint8 uart_no,uint32 ena_mask)
|
||||
{
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(uart_no), ena_mask);
|
||||
}
|
||||
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_SetPrintPort(uint8 uart_no)
|
||||
{
|
||||
if(uart_no==1){
|
||||
os_install_putc1(uart1_write_char);
|
||||
}else{
|
||||
/*option 1: do not wait if uart fifo is full,drop current character*/
|
||||
os_install_putc1(uart0_write_char_no_wait);
|
||||
/*option 2: wait for a while if uart fifo is full*/
|
||||
os_install_putc1(uart0_write_char);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//========================================================
|
||||
|
||||
|
||||
/*test code*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
uart_init_2(UartBautRate uart0_br, UartBautRate uart1_br)
|
||||
{
|
||||
// rom use 74880 baut_rate, here reinitialize
|
||||
UartDev.baut_rate = uart0_br;
|
||||
UartDev.exist_parity = STICK_PARITY_EN;
|
||||
UartDev.parity = EVEN_BITS;
|
||||
UartDev.stop_bits = ONE_STOP_BIT;
|
||||
UartDev.data_bits = EIGHT_BITS;
|
||||
|
||||
uart_config(UART0);
|
||||
UartDev.baut_rate = uart1_br;
|
||||
uart_config(UART1);
|
||||
ETS_UART_INTR_ENABLE();
|
||||
|
||||
// install uart1 putc callback
|
||||
os_install_putc1((void *)uart1_write_char);//print output at UART1
|
||||
}
|
||||
|
||||
/**
|
||||
* Discard any data in the RX buffer.
|
||||
*/
|
||||
int uart_rx_discard() {
|
||||
int oldRxBufferLen = rxBufferLen;
|
||||
rxBufferLen = 0;
|
||||
return oldRxBufferLen;
|
||||
} // End of uart_rx_discard
|
||||
15
targets/esp8266/user_config.h
Normal file
15
targets/esp8266/user_config.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* This file is part of Espruino/ESP8266, a JavaScript interpreter for ESP8266
|
||||
*
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef TARGETS_ESP8266_USER_CONFIG_H_
|
||||
#define TARGETS_ESP8266_USER_CONFIG_H_
|
||||
|
||||
|
||||
|
||||
#endif /* TARGETS_ESP8266_USER_CONFIG_H_ */
|
||||
232
targets/esp8266/user_main.c
Normal file
232
targets/esp8266/user_main.c
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* This file is part of Espruino/ESP8266, a JavaScript interpreter for ESP8266
|
||||
*
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <user_interface.h>
|
||||
#include <osapi.h>
|
||||
#include <driver/uart.h>
|
||||
#include <telnet.h>
|
||||
#include <espmissingincludes.h>
|
||||
|
||||
//#define FAKE_STDLIB
|
||||
#define _GCC_WRAP_STDINT_H
|
||||
typedef long long int64_t;
|
||||
|
||||
#include <jsdevices.h>
|
||||
#include <jsinteractive.h>
|
||||
#include <jswrap_esp8266.h>
|
||||
#include "ESP8266_board.h"
|
||||
|
||||
// --- Constants
|
||||
// The size of the task queue
|
||||
#define TASK_QUEUE_LENGTH 10
|
||||
|
||||
// Should we introduce a ticker to say we are still alive?
|
||||
//#define EPS8266_BOARD_HEARTBEAT
|
||||
|
||||
// --- Forward definitions
|
||||
static void mainLoop();
|
||||
|
||||
// --- File local variables
|
||||
|
||||
// The task queue for the app
|
||||
static os_event_t taskAppQueue[TASK_QUEUE_LENGTH];
|
||||
|
||||
// Flag indicating whether or not main loop processing is suspended.
|
||||
static bool suspendMainLoopFlag = false;
|
||||
|
||||
// Time structure for main loop time suspension.
|
||||
static os_timer_t mainLoopSuspendTimer;
|
||||
|
||||
// --- Functions
|
||||
/**
|
||||
* \brief Dump the ESP8266 restart information.
|
||||
* This is purely for debugging.
|
||||
* When an ESP8266 crashes, before it ends, it records its exception information.
|
||||
* This function retrieves that data and logs it.
|
||||
*/
|
||||
static void dumpRestart() {
|
||||
struct rst_info *rstInfo = system_get_rst_info();
|
||||
os_printf("Restart info:\n");
|
||||
os_printf(" reason: %d\n", rstInfo->reason);
|
||||
os_printf(" exccause: %x\n", rstInfo->exccause);
|
||||
os_printf(" epc1: %x\n", rstInfo->epc1);
|
||||
os_printf(" epc2: %x\n", rstInfo->epc2);
|
||||
os_printf(" epc3: %x\n", rstInfo->epc3);
|
||||
os_printf(" excvaddr: %x\n", rstInfo->excvaddr);
|
||||
os_printf(" depc: %x\n", rstInfo->depc);
|
||||
} // End of dump_restart
|
||||
|
||||
|
||||
/**
|
||||
* \brief Queue a task for the main loop.
|
||||
*/
|
||||
static void queueTaskMainLoop() {
|
||||
system_os_post(TASK_APP_QUEUE, TASK_APP_MAINLOOP, 0);
|
||||
} // End of queueMainLoop
|
||||
|
||||
|
||||
/**
|
||||
* \brief Suspend processing the main loop for a period of time.
|
||||
*/
|
||||
void suspendMainLoop(
|
||||
uint32 interval //!<
|
||||
) {
|
||||
suspendMainLoopFlag = true;
|
||||
os_timer_arm(&mainLoopSuspendTimer, interval, 0 /* No repeat */);
|
||||
} // End of suspendMainLoop
|
||||
|
||||
|
||||
/**
|
||||
* \brief Enable main loop processing.
|
||||
*/
|
||||
static void enableMainLoop() {
|
||||
suspendMainLoopFlag = false;
|
||||
queueTaskMainLoop();
|
||||
} // End of enableMainLoop
|
||||
|
||||
|
||||
/**
|
||||
* \brief The event handler for ESP8266 tasks as created by system_os_post() on the TASK_APP_QUEUE.
|
||||
*/
|
||||
static void eventHandler(
|
||||
os_event_t *pEvent //!<
|
||||
) {
|
||||
|
||||
switch (pEvent->sig) {
|
||||
// Handle the main loop event.
|
||||
case TASK_APP_MAINLOOP:
|
||||
mainLoop();
|
||||
break;
|
||||
// Handle the event to process received data.
|
||||
case TASK_APP_RX_DATA:
|
||||
{
|
||||
// Get the data from the UART RX buffer. If the size of the returned data is
|
||||
// not zero, then push it onto the Espruino processing queue for characters.
|
||||
char pBuffer[100];
|
||||
int size = getRXBuffer(pBuffer, sizeof(pBuffer));
|
||||
if (size > 0) {
|
||||
jshPushIOCharEvents(jsiGetConsoleDevice(), pBuffer, size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
// Handle the unknown event type.
|
||||
default:
|
||||
os_printf("user_main: eventHandler: Unknown task type: %d",
|
||||
pEvent->sig);
|
||||
break;
|
||||
}
|
||||
} // End of eventHandler
|
||||
|
||||
|
||||
/**
|
||||
* \brief A callback function to be invoked when a line has been entered on the telnet client.
|
||||
* Here we want to pass that line to the JS parser for processing.
|
||||
*/
|
||||
static void telnetLineCB(char *line) {
|
||||
jsiConsolePrintf("LineCB: %s", line);
|
||||
// Pass the line to the interactive module ...
|
||||
|
||||
jshPushIOCharEvents(jsiGetConsoleDevice(), line, strlen(line));
|
||||
//jspEvaluate(line, true);
|
||||
//jsiDumpState();
|
||||
telnet_send("JS> ");
|
||||
} // End of lineCB
|
||||
|
||||
|
||||
/**
|
||||
* When we have been allocated a TCP/IP address, this function is called back. Obviously
|
||||
* there is little we can do at the network level until we have an IP.
|
||||
*/
|
||||
static void gotIpCallback() {
|
||||
telnet_startListening(telnetLineCB);
|
||||
} // End of gotIpCallback
|
||||
|
||||
|
||||
/**
|
||||
* \brief Perform the main loop processing.
|
||||
* This is where work is performed
|
||||
* as often as possible.
|
||||
*/
|
||||
static void mainLoop() {
|
||||
if (suspendMainLoopFlag == true) {
|
||||
return;
|
||||
}
|
||||
jsiLoop();
|
||||
|
||||
#ifdef EPS8266_BOARD_HEARTBEAT
|
||||
if (system_get_time() - lastTime > 1000 * 1000 * 5) {
|
||||
lastTime = system_get_time();
|
||||
os_printf("tick: %d\n", jshGetSystemTime());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Setup for another callback
|
||||
queueTaskMainLoop();
|
||||
} // End of mainLoop
|
||||
|
||||
|
||||
/**
|
||||
* The ESP8266 provides a mechanism to register a callback that is invoked when initialization
|
||||
* of the ESP8266 is complete. This is the implementation of that callback. At this point
|
||||
* we can assume that the ESP8266 is fully ready to do work for us.
|
||||
*/
|
||||
static void initDone() {
|
||||
os_printf("initDone invoked\n");
|
||||
|
||||
// Discard any junk data in the input as this is a boot.
|
||||
//uart_rx_discard();
|
||||
|
||||
jshInit(); // Initialize the hardware
|
||||
jsvInit(); // Initialize the variables
|
||||
jsiInit(false); // Initialize the interactive subsystem
|
||||
|
||||
// Register the event handlers.
|
||||
system_os_task(eventHandler, TASK_APP_QUEUE, taskAppQueue, TASK_QUEUE_LENGTH);
|
||||
|
||||
// At this point, our JavaScript environment should be up and running.
|
||||
|
||||
// Initialize the networking subsystem.
|
||||
jswrap_ESP8266WiFi_init();
|
||||
|
||||
// Post the first event to get us going.
|
||||
queueTaskMainLoop();
|
||||
|
||||
return;
|
||||
} // End of initDone
|
||||
|
||||
|
||||
/**
|
||||
* This is a required function needed for ESP8266 SDK. In 99.999% of the instances, this function
|
||||
* needs to be present but have no body. It isn't 100% known what this function does other than
|
||||
* provide an architected callback during initializations. However, its purpose is unknown.
|
||||
*/
|
||||
void user_rf_pre_init() {
|
||||
} // End of user_rf_pre_init
|
||||
|
||||
|
||||
/**
|
||||
* \brief The main entry point in an ESP8266 application.
|
||||
* It is where the logic of ESP8266 starts.
|
||||
*/
|
||||
void user_init() {
|
||||
// Initialize the UART devices
|
||||
uart_init(BIT_RATE_115200, BIT_RATE_115200);
|
||||
UART_SetPrintPort(1);
|
||||
|
||||
// Dump the restart exception information.
|
||||
dumpRestart();
|
||||
|
||||
// Register the ESP8266 initialization callback.
|
||||
system_init_done_cb(initDone);
|
||||
|
||||
// Do NOT attempt to auto connect to an access point.
|
||||
//wifi_station_set_auto_connect(0);
|
||||
os_timer_setfn(&mainLoopSuspendTimer, enableMainLoop, NULL);
|
||||
} // End of user_init
|
||||
// End of file
|
||||
Loading…
x
Reference in New Issue
Block a user