mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
parent
07aac1cc11
commit
908ed13cf6
@ -43,6 +43,6 @@ board_css = """
|
||||
""";
|
||||
|
||||
def get_pins():
|
||||
pins = pinutils.generate_pins(0,7)
|
||||
# just fake pins D0 .. D7
|
||||
return pins
|
||||
pins = pinutils.generate_pins(0,15)
|
||||
# just fake pins D0 .. D15
|
||||
return pins
|
||||
2
doxygen/.gitignore
vendored
Normal file
2
doxygen/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/html/
|
||||
/latex/
|
||||
@ -1,3 +1,5 @@
|
||||
// Because the ESP8266 JS wrapper is assured to be running on an ESP8266 we
|
||||
// can assume that inclusion of ESP8266 headers will be acceptable.
|
||||
#include <c_types.h>
|
||||
#include <user_interface.h>
|
||||
#include <mem.h>
|
||||
@ -60,7 +62,13 @@ static struct ping_option pingOpt;
|
||||
["gotIpCallback", "JsVar", "An optional callback invoked when we have an IP"]
|
||||
]
|
||||
}*/
|
||||
void jswrap_ESP8266WiFi_connect(JsVar *jsv_ssid, JsVar *jsv_password, JsVar *gotIpCallback) {
|
||||
void jswrap_ESP8266WiFi_connect(
|
||||
JsVar *jsv_ssid, //!< The SSID of the access point to connect.
|
||||
JsVar *jsv_password, //!< The password for the access point.
|
||||
JsVar *gotIpCallback //!< The Callback function to be called when we are connected.
|
||||
) {
|
||||
os_printf("> jswrap_ESP8266WiFi_connect\n");
|
||||
|
||||
// Check that the ssid and password values aren't obviously in error.
|
||||
if (jsv_ssid == NULL || !jsvIsString(jsv_ssid)) {
|
||||
jsExceptionHere(JSET_ERROR, "No SSID.");
|
||||
@ -86,6 +94,8 @@ void jswrap_ESP8266WiFi_connect(JsVar *jsv_ssid, JsVar *jsv_password, JsVar *got
|
||||
jsvUnLock(jsGotIpCallback);
|
||||
jsGotIpCallback = NULL;
|
||||
}
|
||||
|
||||
// What does this do?
|
||||
if (gotIpCallback != NULL) {
|
||||
jsGotIpCallback = jsvLockAgainSafe(gotIpCallback);
|
||||
}
|
||||
@ -98,8 +108,7 @@ void jswrap_ESP8266WiFi_connect(JsVar *jsv_ssid, JsVar *jsv_password, JsVar *got
|
||||
len = jsvGetString(jsv_password, password, sizeof(password)-1);
|
||||
password[len]='\0';
|
||||
|
||||
jsiConsolePrintf("jswrap_ESP8266WiFi_connect: %s - %s\r\n", ssid, password);
|
||||
|
||||
os_printf("> - ssid=%s, password=%s\n", ssid, password);
|
||||
// Set the WiFi mode of the ESP8266
|
||||
wifi_set_opmode_current(STATION_MODE);
|
||||
|
||||
@ -115,10 +124,11 @@ void jswrap_ESP8266WiFi_connect(JsVar *jsv_ssid, JsVar *jsv_password, JsVar *got
|
||||
// Set the WiFi configuration
|
||||
wifi_station_set_config(&stationConfig);
|
||||
|
||||
// Register the event handler
|
||||
// Register the event handler for callbacks from ESP8266
|
||||
wifi_set_event_handler_cb(wifiEventHandler);
|
||||
|
||||
wifi_station_connect();
|
||||
os_printf("< jswrap_ESP8266WiFi_connect\n");
|
||||
} // End of jswrap_ESP8266WiFi_connect
|
||||
|
||||
|
||||
@ -209,24 +219,26 @@ void jswrap_ESP8266WiFi_beAccessPoint(
|
||||
void jswrap_ESP8266WiFi_getAccessPoints(
|
||||
JsVar *callback //!< Function to call back when access points retrieved.
|
||||
) {
|
||||
jsiConsolePrint("> ESP8266WiFi_getAccessPoints\n");
|
||||
os_printf("> ESP8266WiFi_getAccessPoints\n");
|
||||
if (callback == NULL || !jsvIsFunction(callback)) {
|
||||
jsExceptionHere(JSET_ERROR, "No callback.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the callback for the scan
|
||||
// Save the callback for the scan in the global variable called jsScanCallback.
|
||||
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
|
||||
// station mode. The network scan will eventually result in a callback
|
||||
// being executed (scanCB) which will contain the results.
|
||||
|
||||
// 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");
|
||||
os_printf("< ESP8266WiFi_getAccessPoints\n");
|
||||
} // End of jswrap_ESP8266WiFi_getAccessPoints
|
||||
|
||||
|
||||
@ -812,6 +824,7 @@ static void scanCB(void *arg, STATUS status) {
|
||||
* of records.
|
||||
*/
|
||||
|
||||
os_printf(">> scanCB\n");
|
||||
// Create the Empty JS array that will be passed as a parameter to the callback.
|
||||
JsVar *accessPointArray = jsvNewArray(NULL, 0);
|
||||
struct bss_info *bssInfo;
|
||||
@ -851,7 +864,7 @@ static void scanCB(void *arg, STATUS status) {
|
||||
// Add the new record to the array
|
||||
jsvArrayPush(accessPointArray, currentAccessPoint);
|
||||
|
||||
os_printf("ssid: %s\n", bssInfo->ssid);
|
||||
os_printf(" - ssid: %s\n", bssInfo->ssid);
|
||||
bssInfo = STAILQ_NEXT(bssInfo, next);
|
||||
} // End of loop over the records.
|
||||
|
||||
@ -860,6 +873,7 @@ static void scanCB(void *arg, STATUS status) {
|
||||
params[0] = accessPointArray;
|
||||
jsiQueueEvents(NULL, jsScanCallback, params, 1);
|
||||
jsvUnLock(jsScanCallback);
|
||||
os_printf("<< scanCB\n");
|
||||
} // End of scanCB
|
||||
|
||||
|
||||
@ -894,16 +908,19 @@ static void sendWifiEvent(uint32 eventType, JsVar *details) {
|
||||
/**
|
||||
* \brief ESP8266 WiFi Event handler.
|
||||
* This function is called by the ESP8266
|
||||
* environment when significant events happend related to the WiFi environment.
|
||||
* environment when significant events happen 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) {
|
||||
// We have connected to an access point.
|
||||
case EVENT_STAMODE_CONNECTED:
|
||||
os_printf("Event: EVENT_STAMODE_CONNECTED\n");
|
||||
sendWifiEvent(event->event, jsvNewNull());
|
||||
break;
|
||||
|
||||
// We have disconnected or been disconnected from an access point.
|
||||
case EVENT_STAMODE_DISCONNECTED:
|
||||
os_printf("Event: EVENT_STAMODE_DISCONNECTED\n");
|
||||
JsVar *details = jspNewObject(NULL, "EventDetails");
|
||||
@ -913,10 +930,14 @@ static void wifiEventHandler(System_Event_t *event) {
|
||||
ssid[ event->event_info.disconnected.ssid_len] = '\0';
|
||||
sendWifiEvent(event->event, details);
|
||||
break;
|
||||
|
||||
// The authentication information at the access point has changed.
|
||||
case EVENT_STAMODE_AUTHMODE_CHANGE:
|
||||
os_printf("Event: EVENT_STAMODE_AUTHMODE_CHANGE\n");
|
||||
sendWifiEvent(event->event, jsvNewNull());
|
||||
break;
|
||||
|
||||
// We have been allocated an IP address.
|
||||
case EVENT_STAMODE_GOT_IP:
|
||||
os_printf("Event: EVENT_STAMODE_GOT_IP\n");
|
||||
sendWifiEvent(event->event, jsvNewNull());
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
*
|
||||
*/
|
||||
// ESP8266 specific includes
|
||||
#define ESPSDK_1_3_0
|
||||
#include <c_types.h>
|
||||
#include <user_interface.h>
|
||||
#include <mem.h>
|
||||
|
||||
@ -183,24 +183,35 @@ typedef enum {
|
||||
SPIB_MINIMUM,// baudRate is the minimum we'll choose
|
||||
} PACKED_FLAGS JshBaudFlags;
|
||||
|
||||
/**
|
||||
* \brief Definition of an SPI interface.
|
||||
*/
|
||||
typedef struct {
|
||||
int baudRate;
|
||||
JshBaudFlags baudRateSpec;
|
||||
Pin pinSCK;
|
||||
Pin pinMISO;
|
||||
Pin pinMOSI;
|
||||
unsigned char spiMode;
|
||||
bool spiMSB; // MSB first?
|
||||
int baudRate; //!< Baud rate.
|
||||
JshBaudFlags baudRateSpec; //!<
|
||||
Pin pinSCK; //!< Pin to use for clock.
|
||||
Pin pinMISO; //!< Pin to use for Master In/Slave Out.
|
||||
Pin pinMOSI; //!< Pin to use for Master Out/Slave In.
|
||||
unsigned char spiMode; //!<
|
||||
bool spiMSB; //!< MSB first?
|
||||
} PACKED_FLAGS JshSPIInfo;
|
||||
static inline void jshSPIInitInfo(JshSPIInfo *inf) {
|
||||
inf->baudRate = 100000;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialize a JshSPIInfo structure to defaults.
|
||||
*/
|
||||
static inline void jshSPIInitInfo(
|
||||
JshSPIInfo *inf //!< The JshSPIInfo structure to initialize to defaults.
|
||||
) {
|
||||
inf->baudRate = 100000;
|
||||
inf->baudRateSpec = SPIB_DEFAULT;
|
||||
inf->pinSCK = PIN_UNDEFINED;
|
||||
inf->pinMISO = PIN_UNDEFINED;
|
||||
inf->pinMOSI = PIN_UNDEFINED;
|
||||
inf->spiMode = SPIF_SPI_MODE_0;
|
||||
inf->spiMSB = true; // MSB first is default
|
||||
}
|
||||
inf->pinSCK = PIN_UNDEFINED;
|
||||
inf->pinMISO = PIN_UNDEFINED;
|
||||
inf->pinMOSI = PIN_UNDEFINED;
|
||||
inf->spiMode = SPIF_SPI_MODE_0;
|
||||
inf->spiMSB = true; // MSB first is default
|
||||
} // End of jshSPIInitInfo.
|
||||
|
||||
|
||||
/** Set up SPI, if pins are -1 they will be guessed */
|
||||
void jshSPISetup(IOEventFlags device, JshSPIInfo *inf);
|
||||
|
||||
@ -70,6 +70,9 @@ void jsiDebuggerLine(JsVar *line);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* \brief Get the device from the class variable.
|
||||
*/
|
||||
IOEventFlags jsiGetDeviceFromClass(JsVar *class) {
|
||||
// Devices have their Object data set up to something special
|
||||
// See jspNewObject
|
||||
@ -79,7 +82,8 @@ IOEventFlags jsiGetDeviceFromClass(JsVar *class) {
|
||||
return (IOEventFlags)class->varData.str[3];
|
||||
|
||||
return EV_NONE;
|
||||
}
|
||||
} // End of jsiGetDeviceFromClass
|
||||
|
||||
|
||||
JsVar *jsiGetClassNameFromDevice(IOEventFlags device) {
|
||||
const char *deviceName = jshGetDeviceString(device);
|
||||
@ -161,12 +165,16 @@ NO_INLINE void jsiConsolePrint(const char *str) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Perform a printf to the console.
|
||||
* Execute a printf command to the current JS console.
|
||||
*/
|
||||
void jsiConsolePrintf(const char *fmt, ...) {
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
vcbprintf((vcbprintf_callback)jsiConsolePrint,0, fmt, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
} // End of jsiConsolePrintf
|
||||
|
||||
/// Print the contents of a string var from a character position until end of line (adding an extra ' ' to delete a character if there was one)
|
||||
void jsiConsolePrintStringVarUntilEOL(JsVar *v, size_t fromCharacter, size_t maxChars, bool andBackup) {
|
||||
|
||||
407
src/jspin.c
407
src/jspin.c
@ -21,13 +21,22 @@
|
||||
#define PIN_NAMES_DIRECT // work out pin names directly from port + pin in pinInfo
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Validate that the pin is a good pin.
|
||||
* \return True if the pin is valid.
|
||||
*/
|
||||
bool jshIsPinValid(Pin pin) {
|
||||
// Note, PIN_UNDEFINED is always > JSH_PIN_COUNT
|
||||
return pin < JSH_PIN_COUNT && pinInfo[pin].port!=JSH_PORT_NONE;
|
||||
}
|
||||
|
||||
return pin < JSH_PIN_COUNT && pinInfo[pin].port != JSH_PORT_NONE;
|
||||
} // End of jshIsPinValid
|
||||
|
||||
/**
|
||||
* \brief Get a pin value from an encoded strin.
|
||||
* \return A pin value.
|
||||
*/
|
||||
Pin jshGetPinFromString(const char *s) {
|
||||
// !!!FIX!!! This function needs an algorithm description.
|
||||
|
||||
// built in constants
|
||||
|
||||
if (s[0]=='B' && s[1]=='T' && s[2]=='N') {
|
||||
@ -176,221 +185,241 @@ void jshGetPinString(char *result, Pin pin) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a var, convert it to a pin ID (or -1 if it doesn't exist). safe for undefined!
|
||||
Pin jshGetPinFromVar(JsVar *pinv) {
|
||||
if (jsvIsString(pinv) && pinv->varData.str[5]==0/*should never be more than 4 chars!*/) {
|
||||
return jshGetPinFromString(&pinv->varData.str[0]);
|
||||
} else if (jsvIsInt(pinv) /* This also tests for the Pin datatype */) {
|
||||
return (Pin)jsvGetInteger(pinv);
|
||||
} else return PIN_UNDEFINED;
|
||||
}
|
||||
/**
|
||||
* Given a var, convert it to a pin ID (or PIN_UNDEFINED if it doesn't exist). safe for undefined!
|
||||
*/
|
||||
Pin jshGetPinFromVar(
|
||||
JsVar *pinv //!< The class instance representing a Pin.
|
||||
) {
|
||||
if (jsvIsString(pinv) && pinv->varData.str[5]==0/*should never be more than 4 chars!*/) {
|
||||
return jshGetPinFromString(&pinv->varData.str[0]);
|
||||
} else if (jsvIsInt(pinv) /* This also tests for the Pin datatype */) {
|
||||
return (Pin)jsvGetInteger(pinv);
|
||||
} else return PIN_UNDEFINED;
|
||||
} // End of jshGetPinFromVar
|
||||
|
||||
Pin jshGetPinFromVarAndUnLock(JsVar *pinv) {
|
||||
Pin pin = jshGetPinFromVar(pinv);
|
||||
jsvUnLock(pinv);
|
||||
return pin;
|
||||
}
|
||||
Pin jshGetPinFromVarAndUnLock(JsVar *pinv) {
|
||||
Pin pin = jshGetPinFromVar(pinv);
|
||||
jsvUnLock(pinv);
|
||||
return pin;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Whether a pin's state has been set manually or not
|
||||
BITFIELD_DECL(jshPinStateIsManual, JSH_PIN_COUNT); // TODO: This should be set to all 0
|
||||
BITFIELD_DECL(jshPinStateIsManual, JSH_PIN_COUNT); // TODO: This should be set to all 0
|
||||
|
||||
bool jshGetPinStateIsManual(Pin pin) {
|
||||
return BITFIELD_GET(jshPinStateIsManual, pin);
|
||||
}
|
||||
bool jshGetPinStateIsManual(Pin pin) {
|
||||
return BITFIELD_GET(jshPinStateIsManual, pin);
|
||||
}
|
||||
|
||||
void jshSetPinStateIsManual(Pin pin, bool manual) {
|
||||
BITFIELD_SET(jshPinStateIsManual, pin, manual);
|
||||
}
|
||||
void jshSetPinStateIsManual(Pin pin, bool manual) {
|
||||
BITFIELD_SET(jshPinStateIsManual, pin, manual);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool jshPinInput(Pin pin) {
|
||||
bool value = false;
|
||||
if (jshIsPinValid(pin)) {
|
||||
if (!jshGetPinStateIsManual(pin))
|
||||
jshPinSetState(pin, JSHPINSTATE_GPIO_IN);
|
||||
/**
|
||||
* \brief Get the value of a pin.
|
||||
* \return The value of the pin.
|
||||
*/
|
||||
bool jshPinInput(
|
||||
Pin pin //!< The pin to have the value retrieved.
|
||||
) {
|
||||
bool value = false;
|
||||
if (jshIsPinValid(pin)) {
|
||||
if (!jshGetPinStateIsManual(pin))
|
||||
jshPinSetState(pin, JSHPINSTATE_GPIO_IN);
|
||||
|
||||
value = jshPinGetValue(pin);
|
||||
} else jsExceptionHere(JSET_ERROR, "Invalid pin!");
|
||||
return value;
|
||||
value = jshPinGetValue(pin);
|
||||
}
|
||||
// Handle pin being invalid.
|
||||
else jsExceptionHere(JSET_ERROR, "Invalid pin!");
|
||||
return value;
|
||||
} // End of jshPinInput
|
||||
|
||||
|
||||
void jshPinOutput(Pin pin, bool value) {
|
||||
if (jshIsPinValid(pin)) {
|
||||
if (!jshGetPinStateIsManual(pin))
|
||||
jshPinSetState(pin, JSHPINSTATE_GPIO_OUT);
|
||||
jshPinSetValue(pin, value);
|
||||
} else jsExceptionHere(JSET_ERROR, "Invalid pin!");
|
||||
/**
|
||||
* \brief Set the value of a pin.
|
||||
*/
|
||||
void jshPinOutput(
|
||||
Pin pin, //!< The pin to set.
|
||||
bool value //!< The new value to set on the pin.
|
||||
) {
|
||||
if (jshIsPinValid(pin)) {
|
||||
if (!jshGetPinStateIsManual(pin))
|
||||
jshPinSetState(pin, JSHPINSTATE_GPIO_OUT);
|
||||
jshPinSetValue(pin, value);
|
||||
}
|
||||
// Handle pin being invalid.
|
||||
else jsExceptionHere(JSET_ERROR, "Invalid pin!");
|
||||
} // End of jshPinOutput.
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Convert an event type flag into a jshPinFunction for an actual hardware device
|
||||
JshPinFunction jshGetPinFunctionFromDevice(IOEventFlags device) {
|
||||
switch (device) {
|
||||
case EV_SERIAL1 : return JSH_USART1;
|
||||
case EV_SERIAL2 : return JSH_USART2;
|
||||
case EV_SERIAL3 : return JSH_USART3;
|
||||
case EV_SERIAL4 : return JSH_USART4;
|
||||
case EV_SERIAL5 : return JSH_USART5;
|
||||
case EV_SERIAL6 : return JSH_USART6;
|
||||
// Convert an event type flag into a jshPinFunction for an actual hardware device
|
||||
JshPinFunction jshGetPinFunctionFromDevice(IOEventFlags device) {
|
||||
switch (device) {
|
||||
case EV_SERIAL1 : return JSH_USART1;
|
||||
case EV_SERIAL2 : return JSH_USART2;
|
||||
case EV_SERIAL3 : return JSH_USART3;
|
||||
case EV_SERIAL4 : return JSH_USART4;
|
||||
case EV_SERIAL5 : return JSH_USART5;
|
||||
case EV_SERIAL6 : return JSH_USART6;
|
||||
|
||||
case EV_SPI1 : return JSH_SPI1;
|
||||
case EV_SPI2 : return JSH_SPI2;
|
||||
case EV_SPI3 : return JSH_SPI3;
|
||||
case EV_SPI1 : return JSH_SPI1;
|
||||
case EV_SPI2 : return JSH_SPI2;
|
||||
case EV_SPI3 : return JSH_SPI3;
|
||||
|
||||
case EV_I2C1 : return JSH_I2C1;
|
||||
case EV_I2C2 : return JSH_I2C2;
|
||||
case EV_I2C3 : return JSH_I2C3;
|
||||
default: return 0;
|
||||
}
|
||||
case EV_I2C1 : return JSH_I2C1;
|
||||
case EV_I2C2 : return JSH_I2C2;
|
||||
case EV_I2C3 : return JSH_I2C3;
|
||||
default: return 0;
|
||||
}
|
||||
} // End of jshGetPinFunctionFromDevice
|
||||
|
||||
/** Try and find a specific type of function for the given pin. Can be given an invalid pin and will return 0. */
|
||||
JshPinFunction NO_INLINE jshGetPinFunctionForPin(Pin pin, JshPinFunction functionType) {
|
||||
if (!jshIsPinValid(pin)) return 0;
|
||||
int i;
|
||||
for (i=0;i<JSH_PININFO_FUNCTIONS;i++) {
|
||||
if ((pinInfo[pin].functions[i]&JSH_MASK_TYPE) == functionType)
|
||||
return pinInfo[pin].functions[i];
|
||||
}
|
||||
return 0;
|
||||
} // End of jshGetPinFunctionForPin
|
||||
|
||||
/** Try and find a specific type of function for the given pin. Can be given an invalid pin and will return 0. */
|
||||
JshPinFunction NO_INLINE jshGetPinFunctionForPin(Pin pin, JshPinFunction functionType) {
|
||||
if (!jshIsPinValid(pin)) return 0;
|
||||
int i;
|
||||
for (i=0;i<JSH_PININFO_FUNCTIONS;i++) {
|
||||
if ((pinInfo[pin].functions[i]&JSH_MASK_TYPE) == functionType)
|
||||
return pinInfo[pin].functions[i];
|
||||
}
|
||||
return 0;
|
||||
/** Try and find the best pin suitable for the given function. Can return -1. */
|
||||
Pin NO_INLINE jshFindPinForFunction(JshPinFunction functionType, JshPinFunction functionInfo) {
|
||||
#ifdef OLIMEXINO_STM32
|
||||
/** Hack, as you can't mix AFs on the STM32F1, and Olimexino reordered the pins
|
||||
* such that D4(AF1) is before D11(AF0) - and there are no SCK/MISO for AF1! */
|
||||
if (functionType == JSH_SPI1 && functionInfo==JSH_SPI_MOSI) return JSH_PORTD_OFFSET+11;
|
||||
#endif
|
||||
#ifdef PICO
|
||||
/* On the Pico, A9 is used for sensing when USB power is applied. Is someone types in
|
||||
* Serial1.setup(9600) it'll get chosen as it's the first pin, but setting it to an output
|
||||
* totally messes up the STM32 as it's fed with 5V. This ensures that it won't get chosen
|
||||
* UNLESS it is explicitly selected.
|
||||
*
|
||||
* TODO: better way of doing this? A JSH_DONT_DEFAULT flag for pin functions? */
|
||||
if (functionType == JSH_USART1) {
|
||||
if (functionInfo==JSH_USART_TX) return JSH_PORTB_OFFSET+6;
|
||||
if (functionInfo==JSH_USART_RX) return JSH_PORTB_OFFSET+7;
|
||||
}
|
||||
#endif
|
||||
Pin i;
|
||||
int j;
|
||||
// first, try and find the pin with an AF of 0 - this is usually the 'default'
|
||||
for (i=0;i<JSH_PIN_COUNT;i++)
|
||||
for (j=0;j<JSH_PININFO_FUNCTIONS;j++)
|
||||
if ((pinInfo[i].functions[j]&JSH_MASK_AF) == JSH_AF0 &&
|
||||
(pinInfo[i].functions[j]&JSH_MASK_TYPE) == functionType &&
|
||||
(pinInfo[i].functions[j]&JSH_MASK_INFO) == functionInfo)
|
||||
return i;
|
||||
// otherwise just try and find anything
|
||||
for (i=0;i<JSH_PIN_COUNT;i++)
|
||||
for (j=0;j<JSH_PININFO_FUNCTIONS;j++)
|
||||
if ((pinInfo[i].functions[j]&JSH_MASK_TYPE) == functionType &&
|
||||
(pinInfo[i].functions[j]&JSH_MASK_INFO) == functionInfo)
|
||||
return i;
|
||||
return PIN_UNDEFINED;
|
||||
} // End of jshFindPinForFunction
|
||||
|
||||
/** Try and find the best pin suitable for the given function. Can return -1. */
|
||||
Pin NO_INLINE jshFindPinForFunction(JshPinFunction functionType, JshPinFunction functionInfo) {
|
||||
#ifdef OLIMEXINO_STM32
|
||||
/** Hack, as you can't mix AFs on the STM32F1, and Olimexino reordered the pins
|
||||
* such that D4(AF1) is before D11(AF0) - and there are no SCK/MISO for AF1! */
|
||||
if (functionType == JSH_SPI1 && functionInfo==JSH_SPI_MOSI) return JSH_PORTD_OFFSET+11;
|
||||
#endif
|
||||
#ifdef PICO
|
||||
/* On the Pico, A9 is used for sensing when USB power is applied. Is someone types in
|
||||
* Serial1.setup(9600) it'll get chosen as it's the first pin, but setting it to an output
|
||||
* totally messes up the STM32 as it's fed with 5V. This ensures that it won't get chosen
|
||||
* UNLESS it is explicitly selected.
|
||||
*
|
||||
* TODO: better way of doing this? A JSH_DONT_DEFAULT flag for pin functions? */
|
||||
if (functionType == JSH_USART1) {
|
||||
if (functionInfo==JSH_USART_TX) return JSH_PORTB_OFFSET+6;
|
||||
if (functionInfo==JSH_USART_RX) return JSH_PORTB_OFFSET+7;
|
||||
}
|
||||
#endif
|
||||
Pin i;
|
||||
int j;
|
||||
// first, try and find the pin with an AF of 0 - this is usually the 'default'
|
||||
for (i=0;i<JSH_PIN_COUNT;i++)
|
||||
for (j=0;j<JSH_PININFO_FUNCTIONS;j++)
|
||||
if ((pinInfo[i].functions[j]&JSH_MASK_AF) == JSH_AF0 &&
|
||||
(pinInfo[i].functions[j]&JSH_MASK_TYPE) == functionType &&
|
||||
(pinInfo[i].functions[j]&JSH_MASK_INFO) == functionInfo)
|
||||
return i;
|
||||
// otherwise just try and find anything
|
||||
for (i=0;i<JSH_PIN_COUNT;i++)
|
||||
for (j=0;j<JSH_PININFO_FUNCTIONS;j++)
|
||||
if ((pinInfo[i].functions[j]&JSH_MASK_TYPE) == functionType &&
|
||||
(pinInfo[i].functions[j]&JSH_MASK_INFO) == functionInfo)
|
||||
return i;
|
||||
return PIN_UNDEFINED;
|
||||
}
|
||||
|
||||
/// Given a full pin function, return a string describing it depending of what's in the flags enum
|
||||
void jshPinFunctionToString(JshPinFunction pinFunc, JshPinFunctionToStringFlags flags, char *buf, size_t bufSize) {
|
||||
const char *devStr = "";
|
||||
JshPinFunction info = JSH_MASK_INFO & pinFunc;
|
||||
JshPinFunction firstDevice = 0;
|
||||
const char *infoStr = 0;
|
||||
buf[0]=0;
|
||||
if (JSH_PINFUNCTION_IS_USART(pinFunc)) {
|
||||
devStr="USART";
|
||||
firstDevice=JSH_USART1;
|
||||
if (info==JSH_USART_RX) infoStr="RX";
|
||||
else if (info==JSH_USART_TX) infoStr="TX";
|
||||
else if (info==JSH_USART_CK) infoStr="CK";
|
||||
} else if (JSH_PINFUNCTION_IS_SPI(pinFunc)) {
|
||||
devStr="SPI";
|
||||
firstDevice=JSH_SPI1;
|
||||
if (info==JSH_SPI_MISO) infoStr="MISO";
|
||||
else if (info==JSH_SPI_MOSI) infoStr="MOSI";
|
||||
else if (info==JSH_SPI_SCK) infoStr="SCK";
|
||||
} else if (JSH_PINFUNCTION_IS_I2C(pinFunc)) {
|
||||
devStr="I2C";
|
||||
firstDevice=JSH_I2C1;
|
||||
if (info==JSH_I2C_SCL) infoStr="SCL";
|
||||
else if (info==JSH_I2C_SDA) infoStr="SDA";
|
||||
} else if (JSH_PINFUNCTION_IS_DAC(pinFunc)) {
|
||||
devStr="DAC";
|
||||
firstDevice=JSH_DAC;
|
||||
if (info==JSH_DAC_CH1) infoStr="CH1";
|
||||
else if (info==JSH_DAC_CH2) infoStr="CH2";
|
||||
} else if (JSH_PINFUNCTION_IS_TIMER(pinFunc)) {
|
||||
devStr="TIM";
|
||||
firstDevice=JSH_TIMER1;
|
||||
char infoStrBuf[5];
|
||||
infoStr = &infoStrBuf[0];
|
||||
infoStrBuf[0] = 'C';
|
||||
infoStrBuf[1] = 'H';
|
||||
infoStrBuf[2] = (char)('1' + ((info&JSH_MASK_TIMER_CH)>>JSH_SHIFT_INFO));
|
||||
if (info & JSH_TIMER_NEGATED) {
|
||||
infoStrBuf[3]='N';
|
||||
infoStrBuf[4] = 0;
|
||||
} else {
|
||||
infoStrBuf[3] = 0;
|
||||
}
|
||||
/// Given a full pin function, return a string describing it depending of what's in the flags enum
|
||||
void jshPinFunctionToString(JshPinFunction pinFunc, JshPinFunctionToStringFlags flags, char *buf, size_t bufSize) {
|
||||
const char *devStr = "";
|
||||
JshPinFunction info = JSH_MASK_INFO & pinFunc;
|
||||
JshPinFunction firstDevice = 0;
|
||||
const char *infoStr = 0;
|
||||
buf[0]=0;
|
||||
if (JSH_PINFUNCTION_IS_USART(pinFunc)) {
|
||||
devStr="USART";
|
||||
firstDevice=JSH_USART1;
|
||||
if (info==JSH_USART_RX) infoStr="RX";
|
||||
else if (info==JSH_USART_TX) infoStr="TX";
|
||||
else if (info==JSH_USART_CK) infoStr="CK";
|
||||
} else if (JSH_PINFUNCTION_IS_SPI(pinFunc)) {
|
||||
devStr="SPI";
|
||||
firstDevice=JSH_SPI1;
|
||||
if (info==JSH_SPI_MISO) infoStr="MISO";
|
||||
else if (info==JSH_SPI_MOSI) infoStr="MOSI";
|
||||
else if (info==JSH_SPI_SCK) infoStr="SCK";
|
||||
} else if (JSH_PINFUNCTION_IS_I2C(pinFunc)) {
|
||||
devStr="I2C";
|
||||
firstDevice=JSH_I2C1;
|
||||
if (info==JSH_I2C_SCL) infoStr="SCL";
|
||||
else if (info==JSH_I2C_SDA) infoStr="SDA";
|
||||
} else if (JSH_PINFUNCTION_IS_DAC(pinFunc)) {
|
||||
devStr="DAC";
|
||||
firstDevice=JSH_DAC;
|
||||
if (info==JSH_DAC_CH1) infoStr="CH1";
|
||||
else if (info==JSH_DAC_CH2) infoStr="CH2";
|
||||
} else if (JSH_PINFUNCTION_IS_TIMER(pinFunc)) {
|
||||
devStr="TIM";
|
||||
firstDevice=JSH_TIMER1;
|
||||
char infoStrBuf[5];
|
||||
infoStr = &infoStrBuf[0];
|
||||
infoStrBuf[0] = 'C';
|
||||
infoStrBuf[1] = 'H';
|
||||
infoStrBuf[2] = (char)('1' + ((info&JSH_MASK_TIMER_CH)>>JSH_SHIFT_INFO));
|
||||
if (info & JSH_TIMER_NEGATED) {
|
||||
infoStrBuf[3]='N';
|
||||
infoStrBuf[4] = 0;
|
||||
} else {
|
||||
infoStrBuf[3] = 0;
|
||||
}
|
||||
int devIdx = 1 + ((((pinFunc&JSH_MASK_TYPE) - firstDevice) >> JSH_SHIFT_TYPE));
|
||||
}
|
||||
int devIdx = 1 + ((((pinFunc&JSH_MASK_TYPE) - firstDevice) >> JSH_SHIFT_TYPE));
|
||||
|
||||
if (!devStr) {
|
||||
jsiConsolePrintf("Couldn't convert pin function %d\n", pinFunc);
|
||||
return;
|
||||
}
|
||||
if (flags & JSPFTS_DEVICE) strncat(buf, devStr, bufSize);
|
||||
if (flags & JSPFTS_DEVICE_NUMBER) itostr(devIdx, &buf[strlen(buf)], 10);
|
||||
if (flags & JSPFTS_SPACE) strncat(buf, " ", bufSize);
|
||||
if (infoStr && (flags & JSPFTS_TYPE)) strncat(buf, infoStr, bufSize);
|
||||
if (!devStr) {
|
||||
jsiConsolePrintf("Couldn't convert pin function %d\n", pinFunc);
|
||||
return;
|
||||
}
|
||||
if (flags & JSPFTS_DEVICE) strncat(buf, devStr, bufSize);
|
||||
if (flags & JSPFTS_DEVICE_NUMBER) itostr(devIdx, &buf[strlen(buf)], 10);
|
||||
if (flags & JSPFTS_SPACE) strncat(buf, " ", bufSize);
|
||||
if (infoStr && (flags & JSPFTS_TYPE)) strncat(buf, infoStr, bufSize);
|
||||
}
|
||||
|
||||
/** Prints a list of capable pins, eg:
|
||||
jshPrintCapablePins(..., "PWM", JSH_TIMER1, JSH_TIMERMAX, 0,0, false)
|
||||
jshPrintCapablePins(..., "SPI", JSH_SPI1, JSH_SPIMAX, JSH_MASK_INFO,JSH_SPI_SCK, false)
|
||||
jshPrintCapablePins(..., "Analog Input", 0,0,0,0, true) - for analogs */
|
||||
void NO_INLINE jshPrintCapablePins(Pin existingPin, const char *functionName, JshPinFunction typeMin, JshPinFunction typeMax, JshPinFunction pMask, JshPinFunction pData, bool printAnalogs) {
|
||||
if (functionName) {
|
||||
jsError("Pin %p is not capable of %s\nSuitable pins are:", existingPin, functionName);
|
||||
}
|
||||
|
||||
/** Prints a list of capable pins, eg:
|
||||
jshPrintCapablePins(..., "PWM", JSH_TIMER1, JSH_TIMERMAX, 0,0, false)
|
||||
jshPrintCapablePins(..., "SPI", JSH_SPI1, JSH_SPIMAX, JSH_MASK_INFO,JSH_SPI_SCK, false)
|
||||
jshPrintCapablePins(..., "Analog Input", 0,0,0,0, true) - for analogs */
|
||||
void NO_INLINE jshPrintCapablePins(Pin existingPin, const char *functionName, JshPinFunction typeMin, JshPinFunction typeMax, JshPinFunction pMask, JshPinFunction pData, bool printAnalogs) {
|
||||
if (functionName) {
|
||||
jsError("Pin %p is not capable of %s\nSuitable pins are:", existingPin, functionName);
|
||||
}
|
||||
|
||||
Pin pin;
|
||||
int i,n=0;
|
||||
for (pin=0;pin<JSH_PIN_COUNT;pin++) {
|
||||
bool has = false;
|
||||
#ifdef STM32F1
|
||||
int af = 0;
|
||||
#endif
|
||||
if (printAnalogs) {
|
||||
has = pinInfo[pin].analog!=JSH_ANALOG_NONE;
|
||||
} else {
|
||||
for (i=0;i<JSH_PININFO_FUNCTIONS;i++) {
|
||||
JshPinFunction type = pinInfo[pin].functions[i] & JSH_MASK_TYPE;
|
||||
if (type>=typeMin && type<=typeMax && ((pinInfo[pin].functions[i]&pMask)==pData)) {
|
||||
has = true;
|
||||
#ifdef STM32F1
|
||||
af = pinInfo[pin].functions[i] & JSH_MASK_AF;
|
||||
#endif
|
||||
}
|
||||
Pin pin;
|
||||
int i,n=0;
|
||||
for (pin=0;pin<JSH_PIN_COUNT;pin++) {
|
||||
bool has = false;
|
||||
#ifdef STM32F1
|
||||
int af = 0;
|
||||
#endif
|
||||
if (printAnalogs) {
|
||||
has = pinInfo[pin].analog!=JSH_ANALOG_NONE;
|
||||
} else {
|
||||
for (i=0;i<JSH_PININFO_FUNCTIONS;i++) {
|
||||
JshPinFunction type = pinInfo[pin].functions[i] & JSH_MASK_TYPE;
|
||||
if (type>=typeMin && type<=typeMax && ((pinInfo[pin].functions[i]&pMask)==pData)) {
|
||||
has = true;
|
||||
#ifdef STM32F1
|
||||
af = pinInfo[pin].functions[i] & JSH_MASK_AF;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (has) {
|
||||
jsiConsolePrintf("%p",pin);
|
||||
#ifdef STM32F1
|
||||
if (af!=JSH_AF0) jsiConsolePrint("(AF)");
|
||||
#endif
|
||||
jsiConsolePrint(" ");
|
||||
if (n++==8) { n=0; jsiConsolePrint("\n"); }
|
||||
}
|
||||
}
|
||||
jsiConsolePrint("\n");
|
||||
if (has) {
|
||||
jsiConsolePrintf("%p",pin);
|
||||
#ifdef STM32F1
|
||||
if (af!=JSH_AF0) jsiConsolePrint("(AF)");
|
||||
#endif
|
||||
jsiConsolePrint(" ");
|
||||
if (n++==8) { n=0; jsiConsolePrint("\n"); }
|
||||
}
|
||||
}
|
||||
jsiConsolePrint("\n");
|
||||
}
|
||||
|
||||
104
src/jsspi.c
104
src/jsspi.c
@ -14,13 +14,35 @@
|
||||
#include "jsspi.h"
|
||||
#include "jsinteractive.h"
|
||||
|
||||
/**
|
||||
* \brief Dump the internal SPI Info data structure to the console.
|
||||
* This is an internal debugging function.
|
||||
*/
|
||||
void jsspiDumpSPIInfo(JshSPIInfo *inf) {
|
||||
jsiConsolePrintf("baudRate=%d, baudRateSpec=%d, pinSCK=%d, pinMISO=%d, pinMOSI=%d, spiMode=%d, spiMSB=%d\n",
|
||||
inf->baudRate, inf->baudRateSpec, inf->pinSCK, inf->pinMISO, inf->pinMOSI, inf->spiMode, inf->spiMSB);
|
||||
} // End of jsspiDumpSPIInfo
|
||||
|
||||
|
||||
int jsspiHardwareFunc(int data, spi_sender_data *info) {
|
||||
IOEventFlags device = *(IOEventFlags*)info;
|
||||
return jshSPISend(device, data);
|
||||
}
|
||||
|
||||
int jsspiFastSoftwareFunc(int data, spi_sender_data *info) {
|
||||
if (data<0) return -1;
|
||||
|
||||
/**
|
||||
* \brief Send a single byte through SPI.
|
||||
* \return The received byte.
|
||||
*/
|
||||
int jsspiFastSoftwareFunc(
|
||||
int data, //!< The byte to send through SPI.
|
||||
spi_sender_data *info //!< The configuration of how to send through SPI.
|
||||
) {
|
||||
// Debug
|
||||
// jsiConsolePrintf("jsspiFastSoftwareFunc: data=%x\n", data);
|
||||
if (data<0) {
|
||||
return -1;
|
||||
}
|
||||
JshSPIInfo *inf = (JshSPIInfo*)info;
|
||||
// fast path for common case
|
||||
int bit;
|
||||
@ -30,11 +52,25 @@ int jsspiFastSoftwareFunc(int data, spi_sender_data *info) {
|
||||
jshPinSetValue(inf->pinSCK, 0 );
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
} // End of jsspiFastSoftwareFunc
|
||||
|
||||
int jsspiSoftwareFunc(int data, spi_sender_data *info) {
|
||||
if (data<0) return -1;
|
||||
|
||||
/**
|
||||
* \brief Send a single byte through SPI.
|
||||
* \return The received byte.
|
||||
*/
|
||||
int jsspiSoftwareFunc(
|
||||
int data, //!< The byte to send through SPI.
|
||||
spi_sender_data *info //!< The configuration of how to send through SPI.
|
||||
) {
|
||||
// Debug
|
||||
// jsiConsolePrintf("jsspiSoftwareFunc: data=%x\n", data);
|
||||
if (data < 0) {
|
||||
return -1;
|
||||
}
|
||||
JshSPIInfo *inf = (JshSPIInfo*)info;
|
||||
// Debug
|
||||
// jsspiDumpSPIInfo(inf);
|
||||
|
||||
bool CPHA = (inf->spiMode & SPIF_CPHA)!=0;
|
||||
bool CPOL = (inf->spiMode & SPIF_CPOL)!=0;
|
||||
@ -65,12 +101,28 @@ int jsspiSoftwareFunc(int data, spi_sender_data *info) {
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // End of jsspiSoftwareFunc
|
||||
|
||||
void jsspiPopulateSPIInfo(JshSPIInfo *inf, JsVar *options) {
|
||||
|
||||
/**
|
||||
* \brief Populate a JshSPIInfo structure from a JS Object.
|
||||
* The object properties that are examined are:
|
||||
* * `sck` - The pin to use for the clock.
|
||||
* * `miso` - The pin to use for Master In/Slave Out.
|
||||
* * `mosi` - The pin to use for Master Out/Slave In.
|
||||
* * `baud` - The baud rate value.
|
||||
* * `mode` - The SPI mode.
|
||||
* * `order` - The bit order (one of "msb" or "lsb")
|
||||
*/
|
||||
void jsspiPopulateSPIInfo(
|
||||
JshSPIInfo *inf, //!< The JshSPIInfo structure to populate.
|
||||
JsVar *options //!< The JS object var to parse.
|
||||
) {
|
||||
jshSPIInitInfo(inf);
|
||||
|
||||
// Validate that the options variable is indeed an object.
|
||||
if (jsvIsObject(options)) {
|
||||
inf->pinSCK = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "sck", 0));
|
||||
inf->pinSCK = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "sck", 0));
|
||||
inf->pinMISO = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "miso", 0));
|
||||
inf->pinMOSI = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "mosi", 0));
|
||||
|
||||
@ -94,12 +146,30 @@ void jsspiPopulateSPIInfo(JshSPIInfo *inf, JsVar *options) {
|
||||
jsWarn("SPI order should be 'msb' or 'lsb'");
|
||||
jsvUnLock(v);
|
||||
}
|
||||
}
|
||||
} // End of jsspiPopulateSPIInfo
|
||||
|
||||
/**
|
||||
* \brief Select the SPI send function.
|
||||
* Get the correct SPI send function (and the data to send to it). We do this
|
||||
* by examining the device and determining if it is hardware, software fast
|
||||
* or software regular.
|
||||
* \return True on success, false otherwise.
|
||||
*/
|
||||
bool jsspiGetSendFunction(
|
||||
JsVar *spiDevice, //!< The device that we want to get the SPI drivers for.
|
||||
spi_sender *spiSend, //!< Return the function to called to send SPI data.
|
||||
spi_sender_data *spiSendData //!< Return configuration data needed to drive SPI.
|
||||
) {
|
||||
// The spiSendData is a little ugly. The value set here is either an
|
||||
// JshSPIInfo which is a structure describing the configuration of SPI or else
|
||||
// it is a device id.
|
||||
|
||||
// Get the correct SPI send function (and the data to send to it)
|
||||
bool jsspiGetSendFunction(JsVar *spiDevice, spi_sender *spiSend, spi_sender_data *spiSendData) {
|
||||
IOEventFlags device = jsiGetDeviceFromClass(spiDevice);
|
||||
|
||||
// See if the device is hardware or software.
|
||||
if (DEVICE_IS_SPI(device)) {
|
||||
//
|
||||
// jsiConsolePrintf("SPI is hardware\n");
|
||||
if (!jshIsDeviceInitialised(device)) {
|
||||
JshSPIInfo inf;
|
||||
jshSPIInitInfo(&inf);
|
||||
@ -109,6 +179,8 @@ bool jsspiGetSendFunction(JsVar *spiDevice, spi_sender *spiSend, spi_sender_data
|
||||
*(IOEventFlags*)spiSendData = device;
|
||||
return true;
|
||||
} else if (device == EV_NONE) {
|
||||
// Debug
|
||||
// jsiConsolePrintf("SPI is software\n");
|
||||
JsVar *options = jsvObjectGetChild(spiDevice, DEVICE_OPTIONS_NAME, 0);
|
||||
static JshSPIInfo inf;
|
||||
jsspiPopulateSPIInfo(&inf, options);
|
||||
@ -116,17 +188,19 @@ bool jsspiGetSendFunction(JsVar *spiDevice, spi_sender *spiSend, spi_sender_data
|
||||
|
||||
if (inf.pinMISO == PIN_UNDEFINED &&
|
||||
inf.pinMOSI != PIN_UNDEFINED &&
|
||||
inf.pinSCK != PIN_UNDEFINED &&
|
||||
inf.pinSCK != PIN_UNDEFINED &&
|
||||
inf.spiMode == SPIF_SPI_MODE_0 &&
|
||||
inf.spiMSB)
|
||||
inf.spiMSB) {
|
||||
*spiSend = jsspiFastSoftwareFunc;
|
||||
else
|
||||
} else {
|
||||
*spiSend = jsspiSoftwareFunc;
|
||||
}
|
||||
*spiSendData = inf;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // End of jsspiGetSendFunction
|
||||
|
||||
|
||||
// Send data over SPI. If andReceive is true, write it back into the same buffer
|
||||
bool jsspiSend(JsVar *spiDevice, JsSpiSendFlags flags, char *buf, size_t len) {
|
||||
|
||||
@ -155,10 +155,13 @@ long long stringToIntWithRadix(const char *s, int forceRadix, bool *hasError) {
|
||||
return v;
|
||||
}
|
||||
|
||||
/* convert hex, binary, octal or decimal string into an int */
|
||||
/**
|
||||
* \brief Convert hex, binary, octal or decimal string into an int.
|
||||
*/
|
||||
long long stringToInt(const char *s) {
|
||||
return stringToIntWithRadix(s,0,0);
|
||||
}
|
||||
} // End of stringToInt
|
||||
|
||||
|
||||
NO_INLINE void jsError(const char *fmt, ...) {
|
||||
jsiConsoleRemoveInputLine();
|
||||
@ -322,7 +325,15 @@ void srand(unsigned int seed) {
|
||||
}
|
||||
#endif
|
||||
|
||||
JsVarFloat stringToFloatWithRadix(const char *s, int forceRadix) {
|
||||
|
||||
/**
|
||||
* \brief Convert a string to a JS float variable where the string is of a specific radix.
|
||||
* \return A JS float variable.
|
||||
*/
|
||||
JsVarFloat stringToFloatWithRadix(
|
||||
const char *s, //!< The string to be converted to a float.
|
||||
int forceRadix //!< The radix of the string data.
|
||||
) {
|
||||
// skip whitespace (strange parseFloat behaviour)
|
||||
while (isWhitespace(*s)) s++;
|
||||
|
||||
@ -398,9 +409,16 @@ JsVarFloat stringToFloatWithRadix(const char *s, int forceRadix) {
|
||||
|
||||
if (isNegated) return -v;
|
||||
return v;
|
||||
}
|
||||
} // End of stringToFloatWithRadix
|
||||
|
||||
JsVarFloat stringToFloat(const char *s) {
|
||||
|
||||
/**
|
||||
* \brief convert a string to a floating point JS variable.
|
||||
* \return a JS float variable.
|
||||
*/
|
||||
JsVarFloat stringToFloat(
|
||||
const char *s //!< The string to convert to a float.
|
||||
) {
|
||||
return stringToFloatWithRadix(s,10);
|
||||
}
|
||||
|
||||
@ -493,25 +511,32 @@ JsVarFloat wrapAround(JsVarFloat val, JsVarFloat size) {
|
||||
return val * size;
|
||||
}
|
||||
|
||||
/** Espruino-special printf with a callback
|
||||
* Supported are:
|
||||
* %d = int
|
||||
* %0#d = int padded to length # with 0s
|
||||
* %x = int as hex
|
||||
* %L = JsVarInt
|
||||
* %Lx = JsVarInt as hex
|
||||
* %f = JsVarFloat
|
||||
* %s = string (char *)
|
||||
* %c = char
|
||||
* %v = JsVar * (doesn't have to be a string - it'll be converted)
|
||||
* %q = JsVar * (in quotes, and escaped)
|
||||
* %j = Variable printed as JSON
|
||||
* %t = Type of variable
|
||||
* %p = Pin
|
||||
/**
|
||||
* \brief Espruino-special printf with a callback.
|
||||
*
|
||||
* The supported format specifiers are:
|
||||
* * `%d` = int
|
||||
* * `%0#d` = int padded to length # with 0s
|
||||
* * `%x` = int as hex
|
||||
* * `%L` = JsVarInt
|
||||
* * `%Lx` = JsVarInt as hex
|
||||
* * `%f` = JsVarFloat
|
||||
* * `%s` = string (char *)
|
||||
* * `%c` = char
|
||||
* * `%v` = JsVar * (doesn't have to be a string - it'll be converted)
|
||||
* * `%q` = JsVar * (in quotes, and escaped)
|
||||
* * `%j` = Variable printed as JSON
|
||||
* * `%t` = Type of variable
|
||||
* * `%p` = Pin
|
||||
*
|
||||
* Anything else will assert
|
||||
*/
|
||||
void vcbprintf(vcbprintf_callback user_callback, void *user_data, const char *fmt, va_list argp) {
|
||||
void vcbprintf(
|
||||
vcbprintf_callback user_callback, //!< Unknown
|
||||
void *user_data, //!< Unknown
|
||||
const char *fmt, //!< The format specified
|
||||
va_list argp //!< List of parameter values
|
||||
) {
|
||||
char buf[32];
|
||||
while (*fmt) {
|
||||
if (*fmt == '%') {
|
||||
@ -587,7 +612,8 @@ void vcbprintf(vcbprintf_callback user_callback, void *user_data, const char *fm
|
||||
user_callback(&buf[0], user_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // End of vcbprintf
|
||||
|
||||
|
||||
void cbprintf(vcbprintf_callback user_callback, void *user_data, const char *fmt, ...) {
|
||||
va_list argp;
|
||||
|
||||
@ -13,17 +13,26 @@
|
||||
*/
|
||||
#include "jsvariterator.h"
|
||||
|
||||
/** Iterate over the contents of var, calling callback for each. Contents may be:
|
||||
* * numeric -> output
|
||||
* * a string -> output each character
|
||||
* * array/arraybuffer -> call itself on each element
|
||||
* * object -> call itself object.count times, on object.data
|
||||
/**
|
||||
* \brief Iterate over the contents of the content of a variable, calling callback for each.
|
||||
* Contents may be:
|
||||
* * numeric -> output
|
||||
* * a string -> output each character
|
||||
* * array/arraybuffer -> call itself on each element
|
||||
* object -> call itself object.count times, on object.data
|
||||
*/
|
||||
bool jsvIterateCallback(JsVar *data, void (*callback)(int item, void *callbackData), void *callbackData) {
|
||||
bool jsvIterateCallback(
|
||||
JsVar *data, // The data to iterate over.
|
||||
void (*callback)(int item, void *callbackData), // The callback function invoke.
|
||||
void *callbackData // Data to be passed to the callback function
|
||||
) {
|
||||
bool ok = true;
|
||||
// Handle the data being a single numeric.
|
||||
if (jsvIsNumeric(data)) {
|
||||
callback((int)jsvGetInteger(data), callbackData);
|
||||
} else if (jsvIsObject(data)) {
|
||||
}
|
||||
// Handle the data being an object.
|
||||
else if (jsvIsObject(data)) {
|
||||
JsVar *countVar = jsvObjectGetChild(data, "count", 0);
|
||||
JsVar *dataVar = jsvObjectGetChild(data, "data", 0);
|
||||
if (countVar && dataVar && jsvIsNumeric(countVar)) {
|
||||
@ -35,7 +44,9 @@ bool jsvIterateCallback(JsVar *data, void (*callback)(int item, void *callbackDa
|
||||
jsWarn("If specifying an object, it must be of the form {data : ..., count : N}");
|
||||
}
|
||||
jsvUnLock2(countVar, dataVar);
|
||||
} else if (jsvIsString(data)) {
|
||||
}
|
||||
// Handle the data being a string
|
||||
else if (jsvIsString(data)) {
|
||||
JsvStringIterator it;
|
||||
jsvStringIteratorNew(&it, data, 0);
|
||||
while (jsvStringIteratorHasChar(&it) && ok) {
|
||||
@ -44,7 +55,9 @@ bool jsvIterateCallback(JsVar *data, void (*callback)(int item, void *callbackDa
|
||||
jsvStringIteratorNext(&it);
|
||||
}
|
||||
jsvStringIteratorFree(&it);
|
||||
} else if (jsvIsArrayBuffer(data)) {
|
||||
}
|
||||
// Handle the data being an array buffer
|
||||
else if (jsvIsArrayBuffer(data)) {
|
||||
JsvArrayBufferIterator it;
|
||||
jsvArrayBufferIteratorNew(&it, data, 0);
|
||||
if (JSV_ARRAYBUFFER_GET_SIZE(it.type) == 1 && !JSV_ARRAYBUFFER_IS_SIGNED(it.type)) {
|
||||
@ -60,7 +73,9 @@ bool jsvIterateCallback(JsVar *data, void (*callback)(int item, void *callbackDa
|
||||
}
|
||||
}
|
||||
jsvArrayBufferIteratorFree(&it);
|
||||
} else if (jsvIsIterable(data)) {
|
||||
}
|
||||
// Handle the data being iterable
|
||||
else if (jsvIsIterable(data)) {
|
||||
JsvIterator it;
|
||||
jsvIteratorNew(&it, data);
|
||||
while (jsvIteratorHasElement(&it) && ok) {
|
||||
@ -75,19 +90,36 @@ bool jsvIterateCallback(JsVar *data, void (*callback)(int item, void *callbackDa
|
||||
ok = false;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
} // End of jsvIterateCallback
|
||||
|
||||
static void jsvIterateCallbackCountCb(int n, void *data) {
|
||||
|
||||
/**
|
||||
* \brief An iterable callback that counts how many times it was called.
|
||||
* This is a function that can be supplied to `jsvIterateCallback`.
|
||||
*/
|
||||
static void jsvIterateCallbackCountCb(
|
||||
int n, //!< The current item being iterated. Not used.
|
||||
void *data //!< A pointer to an int that counts how many times we were called.
|
||||
) {
|
||||
NOT_USED(n);
|
||||
int *count = (int*)data;
|
||||
(*count)++;
|
||||
}
|
||||
/** If jsvIterateCallback is called, how many times will it call the callback function? */
|
||||
} // End of jsvIterateCallbackCountCb
|
||||
|
||||
|
||||
/**
|
||||
* \brief Determine how many items are in this variable that will be iterated over.
|
||||
* \return The number of iterations we will call for this variable.
|
||||
*/
|
||||
int jsvIterateCallbackCount(JsVar *var) {
|
||||
// Actually iterate over the variable where the callback function merely increments a counter
|
||||
// that is initially zero. The result will be the number of times the callback for iteration
|
||||
// was invoked and hence the iteration count of the variable.
|
||||
int count = 0;
|
||||
jsvIterateCallback(var, jsvIterateCallbackCountCb, (void *)&count);
|
||||
return count;
|
||||
}
|
||||
} // End of jsvIterateCallbackCount
|
||||
|
||||
|
||||
typedef struct { unsigned char *buf; unsigned int idx, length; } JsvIterateCallbackToBytesData;
|
||||
static void jsvIterateCallbackToBytesCb(int data, void *userData) {
|
||||
|
||||
123
src/jswrap_io.c
123
src/jswrap_io.c
@ -18,20 +18,20 @@
|
||||
#include "jswrap_arraybuffer.h" // for jswrap_io_peek
|
||||
|
||||
/*JSON{
|
||||
"type" : "function",
|
||||
"name" : "peek8",
|
||||
"type" : "function",
|
||||
"name" : "peek8",
|
||||
"generate_full" : "jswrap_io_peek(addr,count,1)",
|
||||
"params" : [
|
||||
["addr","int","The address in memory to read"],
|
||||
["count","int","(optional) the number of items to read. If >1 a Uint8Array will be returned."]
|
||||
"params" : [
|
||||
["addr", "int", "The address in memory to read"],
|
||||
["count", "int", "(optional) the number of items to read. If >1 a Uint8Array will be returned."]
|
||||
],
|
||||
"return" : ["JsVar","The value of memory at the given location"]
|
||||
"return" : ["JsVar","The value of memory at the given location"]
|
||||
}
|
||||
Read 8 bits of memory at the given location - DANGEROUS!
|
||||
*/
|
||||
/*JSON{
|
||||
"type" : "function",
|
||||
"name" : "poke8",
|
||||
"type" : "function",
|
||||
"name" : "poke8",
|
||||
"generate_full" : "jswrap_io_poke(addr,value,1)",
|
||||
"params" : [
|
||||
["addr","int","The address in memory to write"],
|
||||
@ -233,23 +233,34 @@ void jswrap_io_digitalPulse(Pin pin, bool value, JsVar *times) {
|
||||
}
|
||||
|
||||
/*JSON{
|
||||
"type" : "function",
|
||||
"name" : "digitalWrite",
|
||||
"type" : "function",
|
||||
"name" : "digitalWrite",
|
||||
"generate" : "jswrap_io_digitalWrite",
|
||||
"params" : [
|
||||
["pin","JsVar","The pin to use"],
|
||||
["value","int","Whether to pulse high (true) or low (false)"]
|
||||
"params" : [
|
||||
["pin", "JsVar","The pin to use"],
|
||||
["value", "int","Whether to pulse high (true) or low (false)"]
|
||||
]
|
||||
}
|
||||
Set the digital value of the given pin.
|
||||
|
||||
**Note:** if you didn't call `pinMode` beforehand then this function will also reset pin's state to `"output"`
|
||||
|
||||
If pin argument is an array of pins (eg. `[A2,A1,A0]`) the value argument will be treated as an array of bits where the last array element is the least significant bit.
|
||||
If pin argument is an array of pins (eg. `[A2,A1,A0]`) the value argument will be treated
|
||||
as an array of bits where the last array element is the least significant bit.
|
||||
|
||||
In this case, pin values are set last significant bit first (from the right-hand side of the array of pins). This means you can use the same pin multiple times, for example `digitalWrite([A1,A1,A0,A0],0b0101)` would pulse A0 followed by A1.
|
||||
In this case, pin values are set last significant bit first (from the right-hand side
|
||||
of the array of pins). This means you can use the same pin multiple times, for
|
||||
example `digitalWrite([A1,A1,A0,A0],0b0101)` would pulse A0 followed by A1.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Set the output of a GPIO.
|
||||
*/
|
||||
void jswrap_io_digitalWrite(JsVar *pinVar, JsVarInt value) {
|
||||
void jswrap_io_digitalWrite(
|
||||
JsVar *pinVar, //!< A pin or pins.
|
||||
JsVarInt value //!< The value of the output.
|
||||
) {
|
||||
// Handle the case where it is an array of pins.
|
||||
if (jsvIsArray(pinVar)) {
|
||||
JsVarRef pinName = jsvGetLastChild(pinVar); // NOTE: start at end and work back!
|
||||
while (pinName) {
|
||||
@ -261,29 +272,37 @@ void jswrap_io_digitalWrite(JsVar *pinVar, JsVarInt value) {
|
||||
jsvUnLock(pinNamePtr);
|
||||
value = value>>1; // next bit down
|
||||
}
|
||||
} else {
|
||||
Pin pin = jshGetPinFromVar(pinVar);
|
||||
jshPinOutput(pin, value!=0);
|
||||
}
|
||||
}
|
||||
// Handle the case where it is a single pin.
|
||||
else {
|
||||
Pin pin = jshGetPinFromVar(pinVar);
|
||||
jshPinOutput(pin, value != 0);
|
||||
}
|
||||
} // End of jswrap_io_digitalWrite
|
||||
|
||||
|
||||
/*JSON{
|
||||
"type" : "function",
|
||||
"name" : "digitalRead",
|
||||
"type" : "function",
|
||||
"name" : "digitalRead",
|
||||
"generate" : "jswrap_io_digitalRead",
|
||||
"params" : [
|
||||
"params" : [
|
||||
["pin","JsVar","The pin to use"]
|
||||
],
|
||||
"return" : ["int","The digital Value of the Pin"]
|
||||
"return" : ["int","The digital Value of the Pin"]
|
||||
}
|
||||
Get the digital value of the given pin.
|
||||
|
||||
**Note:** if you didn't call `pinMode` beforehand then this function will also reset pin's state to `"input"`
|
||||
|
||||
If the pin argument is an array of pins (eg. `[A2,A1,A0]`) the value returned will be an number where the last array element is the least significant bit, for example if `A0=A1=1` and `A2=0`, `digitalRead([A2,A1,A0]) == 0b011`
|
||||
If the pin argument is an array of pins (eg. `[A2,A1,A0]`) the value returned will be an number where
|
||||
the last array element is the least significant bit, for example if `A0=A1=1` and `A2=0`, `digitalRead([A2,A1,A0]) == 0b011`
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Read the value of a GPIO pin.
|
||||
*/
|
||||
JsVarInt jswrap_io_digitalRead(JsVar *pinVar) {
|
||||
// Hadnle the case where it is an array of pins.
|
||||
if (jsvIsArray(pinVar)) {
|
||||
int pins = 0;
|
||||
JsVarInt value = 0;
|
||||
@ -299,17 +318,19 @@ JsVarInt jswrap_io_digitalRead(JsVar *pinVar) {
|
||||
jsvObjectIteratorFree(&it);
|
||||
if (pins==0) return 0; // return undefined if array empty
|
||||
return value;
|
||||
} else {
|
||||
}
|
||||
// Handle the case where it is a single pin.
|
||||
else {
|
||||
Pin pin = jshGetPinFromVar(pinVar);
|
||||
return jshPinInput(pin);
|
||||
}
|
||||
}
|
||||
} // End of jswrap_io_digitalRead
|
||||
|
||||
/*JSON{
|
||||
"type" : "function",
|
||||
"name" : "pinMode",
|
||||
"type" : "function",
|
||||
"name" : "pinMode",
|
||||
"generate" : "jswrap_io_pinMode",
|
||||
"params" : [
|
||||
"params" : [
|
||||
["pin","pin","The pin to set pin mode for"],
|
||||
["mode","JsVar","The mode - a string that is either 'analog', 'input', 'input_pullup', 'input_pulldown', 'output', 'opendrain', 'af_output' or 'af_opendrain'. Do not include this argument if you want to revert to automatic pin mode setting."]
|
||||
]
|
||||
@ -323,25 +344,33 @@ Set the mode of the given pin.
|
||||
* `output` - Digital output
|
||||
* `opendrain` - Digital output that only ever pulls down to 0v. Sending a logical `1` leaves the pin open circuit
|
||||
* `af_output` - Digital output from built-in peripheral
|
||||
* `af_opendrain` - Digital output from built-in peripheral that only ever pulls down to 0v. Sending a logical `1` leaves the pin open circuit
|
||||
* `af_opendrain` - Digital output from built-in peripheral that only ever pulls down to 0v.
|
||||
* Sending a logical `1` leaves the pin open circuit
|
||||
|
||||
**Note:** `digitalRead`/`digitalWrite`/etc set the pin mode automatically *unless* `pinMode` has been called first. If you want `digitalRead`/etc to set the pin mode automatically after you have called `pinMode`, simply call it again with no mode argument: `pinMode(pin)`
|
||||
**Note:** `digitalRead`/`digitalWrite`/etc set the pin mode automatically *unless* `pinMode` has been called first. If you want `digitalRead`/etc to set the pin mode automatically after you have called `pinMode`, simply call it again with no mode argument: `pinMode(pin)`
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Set the mode of a pin.
|
||||
*/
|
||||
void jswrap_io_pinMode(Pin pin, JsVar *mode) {
|
||||
void jswrap_io_pinMode(
|
||||
Pin pin, //!< The pin to set.
|
||||
JsVar *mode //!< The new mode of the pin.
|
||||
) {
|
||||
if (!jshIsPinValid(pin)) {
|
||||
jsExceptionHere(JSET_ERROR, "Invalid pin");
|
||||
return;
|
||||
}
|
||||
JshPinState m = JSHPINSTATE_UNDEFINED;
|
||||
if (jsvIsString(mode)) {
|
||||
if (jsvIsStringEqual(mode, "analog")) m = JSHPINSTATE_ADC_IN;
|
||||
else if (jsvIsStringEqual(mode, "input")) m = JSHPINSTATE_GPIO_IN;
|
||||
else if (jsvIsStringEqual(mode, "input_pullup")) m = JSHPINSTATE_GPIO_IN_PULLUP;
|
||||
if (jsvIsStringEqual(mode, "analog")) m = JSHPINSTATE_ADC_IN;
|
||||
else if (jsvIsStringEqual(mode, "input")) m = JSHPINSTATE_GPIO_IN;
|
||||
else if (jsvIsStringEqual(mode, "input_pullup")) m = JSHPINSTATE_GPIO_IN_PULLUP;
|
||||
else if (jsvIsStringEqual(mode, "input_pulldown")) m = JSHPINSTATE_GPIO_IN_PULLDOWN;
|
||||
else if (jsvIsStringEqual(mode, "output")) m = JSHPINSTATE_GPIO_OUT;
|
||||
else if (jsvIsStringEqual(mode, "opendrain")) m = JSHPINSTATE_GPIO_OUT_OPENDRAIN;
|
||||
else if (jsvIsStringEqual(mode, "af_output")) m = JSHPINSTATE_AF_OUT;
|
||||
else if (jsvIsStringEqual(mode, "af_opendrain")) m = JSHPINSTATE_AF_OUT_OPENDRAIN;
|
||||
else if (jsvIsStringEqual(mode, "output")) m = JSHPINSTATE_GPIO_OUT;
|
||||
else if (jsvIsStringEqual(mode, "opendrain")) m = JSHPINSTATE_GPIO_OUT_OPENDRAIN;
|
||||
else if (jsvIsStringEqual(mode, "af_output")) m = JSHPINSTATE_AF_OUT;
|
||||
else if (jsvIsStringEqual(mode, "af_opendrain")) m = JSHPINSTATE_AF_OUT_OPENDRAIN;
|
||||
}
|
||||
if (m != JSHPINSTATE_UNDEFINED) {
|
||||
jshSetPinStateIsManual(pin, true);
|
||||
@ -373,14 +402,14 @@ JsVar *jswrap_io_getPinMode(Pin pin) {
|
||||
JshPinState m = jshPinGetState(pin)&JSHPINSTATE_MASK;
|
||||
const char *text = 0;
|
||||
switch (m) {
|
||||
case JSHPINSTATE_ADC_IN : text = "analog"; break;
|
||||
case JSHPINSTATE_GPIO_IN : text = "input"; break;
|
||||
case JSHPINSTATE_GPIO_IN_PULLUP : text = "input_pullup"; break;
|
||||
case JSHPINSTATE_GPIO_IN_PULLDOWN : text = "input_pulldown"; break;
|
||||
case JSHPINSTATE_GPIO_OUT : text = "output"; break;
|
||||
case JSHPINSTATE_ADC_IN : text = "analog"; break;
|
||||
case JSHPINSTATE_GPIO_IN : text = "input"; break;
|
||||
case JSHPINSTATE_GPIO_IN_PULLUP : text = "input_pullup"; break;
|
||||
case JSHPINSTATE_GPIO_IN_PULLDOWN : text = "input_pulldown"; break;
|
||||
case JSHPINSTATE_GPIO_OUT : text = "output"; break;
|
||||
case JSHPINSTATE_GPIO_OUT_OPENDRAIN : text = "opendrain"; break;
|
||||
case JSHPINSTATE_AF_OUT : text = "af_output"; break;
|
||||
case JSHPINSTATE_AF_OUT_OPENDRAIN : text = "af_opendrain"; break;
|
||||
case JSHPINSTATE_AF_OUT : text = "af_output"; break;
|
||||
case JSHPINSTATE_AF_OUT_OPENDRAIN : text = "af_opendrain"; break;
|
||||
default: break;
|
||||
}
|
||||
if (text) return jsvNewFromString(text);
|
||||
|
||||
109
src/jswrap_pin.c
109
src/jswrap_pin.c
@ -18,53 +18,57 @@
|
||||
#include "jstimer.h"
|
||||
|
||||
/*JSON{
|
||||
"type" : "class",
|
||||
"type" : "class",
|
||||
"class" : "Pin",
|
||||
"check" : "jsvIsPin(var)"
|
||||
}
|
||||
This is the built-in class for Pins, such as D0,D1,LED1, or BTN
|
||||
|
||||
You can call the methods on Pin, or you can use Wiring-style functions such as digitalWrite
|
||||
*/
|
||||
*/
|
||||
|
||||
/*JSON{
|
||||
"type" : "constructor",
|
||||
"class" : "Pin",
|
||||
"name" : "Pin",
|
||||
"type" : "constructor",
|
||||
"class" : "Pin",
|
||||
"name" : "Pin",
|
||||
"generate" : "jswrap_pin_constructor",
|
||||
"params" : [
|
||||
["value","JsVar","A value to be converted to a pin. Can be a number, pin, or String."]
|
||||
"params" : [
|
||||
["value", "JsVar", "A value to be converted to a pin. Can be a number, pin, or String."]
|
||||
],
|
||||
"return" : ["JsVar","A Pin object"]
|
||||
"return" : ["JsVar","A Pin object"]
|
||||
}
|
||||
Creates a pin from the given argument (or returns undefined if no argument)
|
||||
*/
|
||||
/**
|
||||
* \brief Create an instance of a Pin class.
|
||||
*/
|
||||
JsVar *jswrap_pin_constructor(JsVar *val) {
|
||||
Pin pin = jshGetPinFromVar(val);
|
||||
if (!jshIsPinValid(pin)) return 0;
|
||||
return jsvNewFromPin(pin);
|
||||
}
|
||||
} // End of jswrap_pin_constructor
|
||||
|
||||
|
||||
/*JSON{
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "read",
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "read",
|
||||
"generate" : "jswrap_pin_read",
|
||||
"return" : ["bool","Whether pin is a logical 1 or 0"]
|
||||
"return" : ["bool","Whether pin is a logical 1 or 0"]
|
||||
}
|
||||
Returns the input state of the pin as a boolean.
|
||||
|
||||
**Note:** if you didn't call `pinMode` beforehand then this function will also reset pin's state to `"input"`
|
||||
*/
|
||||
*/
|
||||
bool jswrap_pin_read(JsVar *parent) {
|
||||
Pin pin = jshGetPinFromVar(parent);
|
||||
return jshPinInput(pin);
|
||||
}
|
||||
|
||||
/*JSON{
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "set",
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "set",
|
||||
"generate" : "jswrap_pin_set"
|
||||
}
|
||||
Sets the output state of the pin to a 1
|
||||
@ -77,9 +81,9 @@ void jswrap_pin_set(JsVar *parent) {
|
||||
}
|
||||
|
||||
/*JSON{
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "reset",
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "reset",
|
||||
"generate" : "jswrap_pin_reset"
|
||||
}
|
||||
Sets the output state of the pin to a 0
|
||||
@ -92,32 +96,35 @@ void jswrap_pin_reset(JsVar *parent) {
|
||||
}
|
||||
|
||||
/*JSON{
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "write",
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "write",
|
||||
"generate" : "jswrap_pin_write",
|
||||
"params" : [
|
||||
["value","bool","Whether to set output high (true/1) or low (false/0)"]
|
||||
"params" : [
|
||||
["value", "bool", "Whether to set output high (true/1) or low (false/0)"]
|
||||
]
|
||||
}
|
||||
Sets the output state of the pin to the parameter given
|
||||
|
||||
**Note:** if you didn't call `pinMode` beforehand then this function will also reset pin's state to `"output"`
|
||||
*/
|
||||
void jswrap_pin_write(JsVar *parent, bool value) {
|
||||
void jswrap_pin_write(
|
||||
JsVar *parent, //!< The class instance representing the Pin.
|
||||
bool value //!< The value to set the pin.
|
||||
) {
|
||||
Pin pin = jshGetPinFromVar(parent);
|
||||
jshPinOutput(pin, value);
|
||||
}
|
||||
} // End of jswrap_pin_write
|
||||
|
||||
/*JSON{
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "writeAtTime",
|
||||
"ifndef" : "SAVE_ON_FLASH",
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "writeAtTime",
|
||||
"ifndef" : "SAVE_ON_FLASH",
|
||||
"generate" : "jswrap_pin_writeAtTime",
|
||||
"params" : [
|
||||
["value","bool","Whether to set output high (true/1) or low (false/0)"],
|
||||
["time","float","Time at which to write"]
|
||||
["value", "bool", "Whether to set output high (true/1) or low (false/0)"],
|
||||
["time", "float", "Time at which to write"]
|
||||
]
|
||||
}
|
||||
Sets the output state of the pin to the parameter given at the specified time.
|
||||
@ -132,11 +139,11 @@ void jswrap_pin_writeAtTime(JsVar *parent, bool value, JsVarFloat time) {
|
||||
|
||||
|
||||
/*JSON{
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "getMode",
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "getMode",
|
||||
"generate" : "jswrap_pin_getMode",
|
||||
"return" : ["JsVar","The pin mode, as a string"]
|
||||
"return" : ["JsVar", "The pin mode, as a string"]
|
||||
}
|
||||
Return the current mode of the given pin. See `pinMode` for more information.
|
||||
*/
|
||||
@ -145,12 +152,12 @@ JsVar *jswrap_pin_getMode(JsVar *parent) {
|
||||
}
|
||||
|
||||
/*JSON{
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "mode",
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "mode",
|
||||
"generate" : "jswrap_pin_mode",
|
||||
"params" : [
|
||||
["mode","JsVar","The mode - a string that is either 'analog', 'input', 'input_pullup', 'input_pulldown', 'output', 'opendrain', 'af_output' or 'af_opendrain'. Do not include this argument if you want to revert to automatic pin mode setting."]
|
||||
["mode", "JsVar", "The mode - a string that is either 'analog', 'input', 'input_pullup', 'input_pulldown', 'output', 'opendrain', 'af_output' or 'af_opendrain'. Do not include this argument if you want to revert to automatic pin mode setting."]
|
||||
]
|
||||
}
|
||||
Set the mode of the given pin. See [`pinMode`](#l__global_pinMode) for more information on pin modes.
|
||||
@ -160,11 +167,11 @@ void jswrap_pin_mode(JsVar *parent, JsVar *mode) {
|
||||
}
|
||||
|
||||
/*JSON{
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "getInfo",
|
||||
"type" : "method",
|
||||
"class" : "Pin",
|
||||
"name" : "getInfo",
|
||||
"generate" : "jswrap_pin_getInfo",
|
||||
"return" : ["JsVar","An object containing information about this pins"]
|
||||
"return" : ["JsVar","An object containing information about this pins"]
|
||||
}
|
||||
Get information about this pin and its capabilities. Of the form:
|
||||
|
||||
@ -178,11 +185,15 @@ Get information about this pin and its capabilities. Of the form:
|
||||
"I2C3":{type:"SCL", af:1}
|
||||
}
|
||||
}
|
||||
|
||||
Will return undefined if pin is not valid.
|
||||
```
|
||||
Will return undefined if pin is not valid.
|
||||
*/
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
JsVar *jswrap_pin_getInfo(JsVar *parent) {
|
||||
JsVar *jswrap_pin_getInfo(
|
||||
JsVar *parent //!< The class instance representing the pin.
|
||||
) {
|
||||
Pin pin = jshGetPinFromVar(parent);
|
||||
if (!jshIsPinValid(pin)) return 0;
|
||||
const JshPinInfo *inf = &pinInfo[pin];
|
||||
@ -231,5 +242,3 @@ JsVar *jswrap_pin_getInfo(JsVar *parent) {
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -61,9 +61,14 @@ Create a software SPI port. This has limited functionality (no baud rate), but i
|
||||
|
||||
Use `SPI.setup` to configure this port.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Create a software based SPI interface.
|
||||
* \return A JS object that will hold the state of the SPI.
|
||||
*/
|
||||
JsVar *jswrap_spi_constructor() {
|
||||
return jsvNewWithFlags(JSV_OBJECT);
|
||||
}
|
||||
} // End of jswrap_spi_constructor
|
||||
|
||||
/*JSON{
|
||||
"type" : "method",
|
||||
@ -76,9 +81,28 @@ JsVar *jswrap_spi_constructor() {
|
||||
}
|
||||
Set up this SPI port as an SPI Master.
|
||||
*/
|
||||
void jswrap_spi_setup(JsVar *parent, JsVar *options) {
|
||||
|
||||
/**
|
||||
* \brief Configure/initialize the software SPI interface.
|
||||
*/
|
||||
void jswrap_spi_setup(
|
||||
JsVar *parent, //!< The variable that is the class instance of this function.
|
||||
JsVar *options //!< The options controlling SPI.
|
||||
) {
|
||||
//
|
||||
// Design: The options variable is a JS Object which contains a series of settings. These
|
||||
// settings are parsed by `jsspiPopulateSPIInfo` to populate a C structure of type
|
||||
// `JshSPIInfo`.
|
||||
//
|
||||
// The options are also hung off the class instance variable in a property symbolically called
|
||||
// DEVICE_OPTIONS_NAME ("_options").
|
||||
//
|
||||
IOEventFlags device = jsiGetDeviceFromClass(parent);
|
||||
JshSPIInfo inf;
|
||||
|
||||
// Debug
|
||||
// jsiConsolePrintf("jswrap_spi_setup called parent=%v, options=%v\n", parent, options);
|
||||
|
||||
jsspiPopulateSPIInfo(&inf, options);
|
||||
|
||||
if (DEVICE_IS_SPI(device)) {
|
||||
@ -102,7 +126,7 @@ void jswrap_spi_setup(JsVar *parent, JsVar *options) {
|
||||
jsvUnLock(jsvSetNamedChild(parent, options, DEVICE_OPTIONS_NAME));
|
||||
else
|
||||
jsvRemoveNamedChild(parent, DEVICE_OPTIONS_NAME);
|
||||
}
|
||||
} // End of jswrap_spi_setup
|
||||
|
||||
|
||||
/*JSON{
|
||||
@ -124,29 +148,57 @@ For maximum speeds, please pass either Strings or Typed Arrays as arguments. Not
|
||||
|
||||
*/
|
||||
typedef struct {
|
||||
spi_sender spiSend;
|
||||
spi_sender_data spiSendData;
|
||||
int rxAmt, txAmt;
|
||||
JsvArrayBufferIterator it;
|
||||
spi_sender spiSend; //!< A function to be called to send SPI data.
|
||||
spi_sender_data spiSendData; //!< Control information on the nature of the SPI interface.
|
||||
int rxAmt; //!<
|
||||
int txAmt; //!<
|
||||
JsvArrayBufferIterator it; //!< A buffer to hold the response data from MISO
|
||||
} jswrap_spi_send_data;
|
||||
|
||||
void jswrap_spi_send_cb(int c, jswrap_spi_send_data *data) {
|
||||
|
||||
/**
|
||||
* \brief Send a single byte to the SPI device.
|
||||
*/
|
||||
void jswrap_spi_send_cb(
|
||||
int c, //!< The byte to send through SPI.
|
||||
jswrap_spi_send_data *data //!< Control information on how to send to SPI.
|
||||
) {
|
||||
// Invoke the SPI send function to transmit the single byte.
|
||||
int result = data->spiSend(c, &data->spiSendData);
|
||||
if (c>=0) data->txAmt++;
|
||||
if (result>=0) {
|
||||
if (c >= 0) {
|
||||
data->txAmt++;
|
||||
}
|
||||
// If we got a result byte, save it.
|
||||
if (result >= 0) {
|
||||
jsvArrayBufferIteratorSetByteValue(&data->it, (char)result);
|
||||
jsvArrayBufferIteratorNext(&data->it);
|
||||
data->rxAmt++;
|
||||
}
|
||||
}
|
||||
} // End of jswrap_spi_send_cb
|
||||
|
||||
JsVar *jswrap_spi_send(JsVar *parent, JsVar *srcdata, Pin nss_pin) {
|
||||
|
||||
/**
|
||||
* \brief Send data through SPI.
|
||||
* The data can be in a variety of formats including:
|
||||
* * `numeric` - A single byte is transmitted.
|
||||
* * `string` - Each character in the string is transmitted.
|
||||
* * `iterable` - An iterable object is transmitted.
|
||||
* \return the Received bytes (MISO). This is byte array.
|
||||
*/
|
||||
JsVar *jswrap_spi_send(
|
||||
JsVar *parent, //!< A description of the SPI device to send data through.
|
||||
JsVar *srcdata, //!< The data to send through SPI.
|
||||
Pin nss_pin //!< The pin to toggle low then high (CS)
|
||||
) {
|
||||
// Debug
|
||||
// jsiConsolePrintf("jswrap_spi_send called: parent=%j, srcdata=%j, nss_pin=%p\n", parent, srcdata, nss_pin);
|
||||
NOT_USED(parent);
|
||||
IOEventFlags device = jsiGetDeviceFromClass(parent);
|
||||
|
||||
jswrap_spi_send_data data;
|
||||
if (!jsspiGetSendFunction(parent, &data.spiSend, &data.spiSendData))
|
||||
if (!jsspiGetSendFunction(parent, &data.spiSend, &data.spiSendData)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
JsVar *dst = 0;
|
||||
|
||||
@ -156,12 +208,16 @@ JsVar *jswrap_spi_send(JsVar *parent, JsVar *srcdata, Pin nss_pin) {
|
||||
// assert NSS
|
||||
if (nss_pin!=PIN_UNDEFINED) jshPinOutput(nss_pin, false);
|
||||
|
||||
// send data
|
||||
// Now that we are setup, we can send the data.
|
||||
|
||||
// Handle the data being a single byte value
|
||||
if (jsvIsNumeric(srcdata)) {
|
||||
int r = data.spiSend((unsigned char)jsvGetInteger(srcdata), &data.spiSendData);
|
||||
if (r<0) r = data.spiSend(-1, &data.spiSendData);
|
||||
dst = jsvNewFromInteger(r); // retrieve the byte (no send!)
|
||||
} else if (jsvIsString(srcdata)) {
|
||||
}
|
||||
// Handle the data being a string
|
||||
else if (jsvIsString(srcdata)) {
|
||||
dst = jsvNewFromEmptyString();
|
||||
JsvStringIterator it;
|
||||
jsvStringIteratorNew(&it, srcdata, 0);
|
||||
@ -184,7 +240,9 @@ JsVar *jswrap_spi_send(JsVar *parent, JsVar *srcdata, Pin nss_pin) {
|
||||
unsigned char out = (unsigned char)data.spiSend(-1, &data.spiSendData);
|
||||
jsvAppendStringBuf(dst, (char*)&out, 1);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
// Handle the data being an iterable.
|
||||
else {
|
||||
int nBytes = jsvIterateCallbackCount(srcdata);
|
||||
dst = jsvNewTypedArray(ARRAYBUFFERVIEW_UINT8, nBytes);
|
||||
if (dst) {
|
||||
@ -193,8 +251,9 @@ JsVar *jswrap_spi_send(JsVar *parent, JsVar *srcdata, Pin nss_pin) {
|
||||
// Write data
|
||||
jsvIterateCallback(srcdata, (void (*)(int, void *))jswrap_spi_send_cb, &data);
|
||||
// Wait until SPI send is finished, and flush data
|
||||
while (data.rxAmt < data.txAmt && !jspIsInterrupted())
|
||||
while (data.rxAmt < data.txAmt && !jspIsInterrupted()) {
|
||||
jswrap_spi_send_cb(-1, &data);
|
||||
}
|
||||
jsvArrayBufferIteratorFree(&data.it);
|
||||
}
|
||||
}
|
||||
@ -202,7 +261,8 @@ JsVar *jswrap_spi_send(JsVar *parent, JsVar *srcdata, Pin nss_pin) {
|
||||
// de-assert NSS
|
||||
if (nss_pin!=PIN_UNDEFINED) jshPinOutput(nss_pin, true);
|
||||
return dst;
|
||||
}
|
||||
} // End of jswrap_spi_send
|
||||
|
||||
|
||||
/*JSON{
|
||||
"type" : "method",
|
||||
@ -217,20 +277,23 @@ Write a character or array of characters to SPI - without reading the result bac
|
||||
|
||||
For maximum speeds, please pass either Strings or Typed Arrays as arguments.
|
||||
*/
|
||||
void jswrap_spi_write(JsVar *parent, JsVar *args) {
|
||||
void jswrap_spi_write(
|
||||
JsVar *parent, //!<
|
||||
JsVar *args //!<
|
||||
) {
|
||||
NOT_USED(parent);
|
||||
IOEventFlags device = jsiGetDeviceFromClass(parent);
|
||||
|
||||
spi_sender spiSend;
|
||||
spi_sender_data spiSendData;
|
||||
if (!jsspiGetSendFunction(parent, &spiSend, &spiSendData))
|
||||
if (!jsspiGetSendFunction(parent, &spiSend, &spiSendData)) {
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
Pin nss_pin = PIN_UNDEFINED;
|
||||
// If the last value is a pin, use it as the NSS pin
|
||||
JsVarInt len = jsvGetArrayLength(args);
|
||||
if (len>0) {
|
||||
if (len > 0) {
|
||||
JsVar *last = jsvGetArrayItem(args, len-1); // look at the last value
|
||||
if (jsvIsPin(last)) {
|
||||
nss_pin = jshGetPinFromVar(last);
|
||||
|
||||
@ -54,12 +54,23 @@ int os_printf_plus(const char *format, ...) __attribute__((format(printf, 1, 2)
|
||||
|
||||
// memory allocation functions are "different" due to memory debugging functionality
|
||||
// added in SDK 1.4.0
|
||||
void vPortFree(void *ptr, char * file, int line);
|
||||
#ifndef ESPSDK_1_3_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 pvPortFree(void *ptr);
|
||||
void *pvPortRealloc(void *pv, size_t size, char * file, int line);
|
||||
#else
|
||||
void vPortFree(void *ptr);
|
||||
void *pvPortMalloc(size_t xWantedSize);
|
||||
void *pvPortZalloc(size_t);
|
||||
void *vPortMalloc(size_t xWantedSize);
|
||||
void pvPortFree(void *ptr);
|
||||
void *pvPortRealloc(void *pv, size_t size);
|
||||
#define os_realloc pvPortRealloc
|
||||
void *pvPortRealloc(void* ptr, size_t size);
|
||||
#endif
|
||||
|
||||
void uart_div_modify(int no, unsigned int freq);
|
||||
uint32 system_get_time();
|
||||
|
||||
@ -176,6 +176,43 @@ static uint8_t pinFunction(JshPinState state) {
|
||||
}
|
||||
} // End of pinFunction
|
||||
|
||||
|
||||
/**
|
||||
* \brief Convert a pin state to a string representation.
|
||||
*/
|
||||
static char *pinStateToString(JshPinState state) {
|
||||
switch(state) {
|
||||
case JSHPINSTATE_ADC_IN:
|
||||
return("JSHPINSTATE_ADC_IN");
|
||||
case JSHPINSTATE_AF_OUT:
|
||||
return("JSHPINSTATE_AF_OUT");
|
||||
case JSHPINSTATE_AF_OUT_OPENDRAIN:
|
||||
return("JSHPINSTATE_AF_OUT_OPENDRAIN");
|
||||
case JSHPINSTATE_DAC_OUT:
|
||||
return("JSHPINSTATE_DAC_OUT");
|
||||
case JSHPINSTATE_GPIO_IN:
|
||||
return("JSHPINSTATE_GPIO_IN");
|
||||
case JSHPINSTATE_GPIO_IN_PULLDOWN:
|
||||
return("JSHPINSTATE_GPIO_IN_PULLDOWN");
|
||||
case JSHPINSTATE_GPIO_IN_PULLUP:
|
||||
return("JSHPINSTATE_GPIO_IN_PULLUP");
|
||||
case JSHPINSTATE_GPIO_OUT:
|
||||
return("JSHPINSTATE_GPIO_OUT");
|
||||
case JSHPINSTATE_GPIO_OUT_OPENDRAIN:
|
||||
return("JSHPINSTATE_GPIO_OUT_OPENDRAIN");
|
||||
case JSHPINSTATE_I2C:
|
||||
return("JSHPINSTATE_I2C");
|
||||
case JSHPINSTATE_UNDEFINED:
|
||||
return("JSHPINSTATE_UNDEFINED");
|
||||
case JSHPINSTATE_USART_IN:
|
||||
return("JSHPINSTATE_USART_IN");
|
||||
case JSHPINSTATE_USART_OUT:
|
||||
return("JSHPINSTATE_USART_OUT");
|
||||
default:
|
||||
return("** unknown **");
|
||||
}
|
||||
} // End of pinStateToString
|
||||
|
||||
/**
|
||||
* \brief Set the state of the specific pin.
|
||||
*
|
||||
@ -198,7 +235,8 @@ static uint8_t pinFunction(JshPinState state) {
|
||||
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);
|
||||
// Debug
|
||||
// os_printf("> ESP8266: jshPinSetState %d, %s\n", pin, pinStateToString(state));
|
||||
|
||||
assert(pin < 16);
|
||||
int periph = PERIPHS_IO_MUX + PERIPHS[pin];
|
||||
@ -250,7 +288,7 @@ void jshPinSetState(Pin pin, //!< The pin to have its state changed.
|
||||
* \return The current state of the selected pin.
|
||||
*/
|
||||
JshPinState jshPinGetState(Pin pin) {
|
||||
jsiConsolePrintf("ESP8266: jshPinGetState %d\n", pin);
|
||||
os_printf("> ESP8266: jshPinGetState %d\n", pin);
|
||||
return JSHPINSTATE_UNDEFINED;
|
||||
} // End of jshPinGetState
|
||||
|
||||
@ -261,7 +299,8 @@ JshPinState jshPinGetState(Pin 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);
|
||||
// Debug
|
||||
// os_printf("> ESP8266: jshPinSetValue %d, %d\n", pin, value);
|
||||
GPIO_OUTPUT_SET(pin, value);
|
||||
} // End of jshPinSetValue
|
||||
|
||||
@ -272,18 +311,19 @@ void jshPinSetValue(Pin pin, //!< The pin to have its value changed.
|
||||
*/
|
||||
bool jshPinGetValue(Pin pin //!< The pin to have its value read.
|
||||
) {
|
||||
jsiConsolePrintf("ESP8266: jshPinGetValue %d, %d\n", pin, GPIO_INPUT_GET(pin));
|
||||
// Debug
|
||||
// os_printf("> 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);
|
||||
os_printf("> ESP8266: jshIsDeviceInitialised %d\n", device);
|
||||
return true;
|
||||
} // End of jshIsDeviceInitialised
|
||||
|
||||
bool jshIsUSBSERIALConnected() {
|
||||
jsiConsolePrintf("ESP8266: jshIsUSBSERIALConnected\n");
|
||||
os_printf("> ESP8266: jshIsUSBSERIALConnected\n");
|
||||
return true;
|
||||
} // End of jshIsUSBSERIALConnected
|
||||
|
||||
@ -312,23 +352,32 @@ JsSysTime jshGetSystemTime() { // in us
|
||||
* Set the current time in microseconds.
|
||||
*/
|
||||
void jshSetSystemTime(JsSysTime time) {
|
||||
os_printf("ESP8266: jshSetSystemTime: %d\n", (int)time);
|
||||
os_printf("> ESP8266: jshSetSystemTime: %d\n", (int)time);
|
||||
} // End of jshSetSystemTime
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
JsVarFloat jshPinAnalog(Pin pin) {
|
||||
jsiConsolePrintf("ESP8266: jshPinAnalog: %d\n", pin);
|
||||
os_printf("> ESP8266: jshPinAnalog: %d\n", pin);
|
||||
return (JsVarFloat) system_adc_read();
|
||||
} // End of jshPinAnalog
|
||||
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
int jshPinAnalogFast(Pin pin) {
|
||||
jsiConsolePrintf("ESP8266: jshPinAnalogFast: %d\n", pin);
|
||||
os_printf("> ESP8266: jshPinAnalogFast: %d\n", pin);
|
||||
return NAN;
|
||||
} // End of jshPinAnalogFast
|
||||
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
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);
|
||||
@ -336,16 +385,25 @@ JshPinFunction jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq, Js
|
||||
} // End of jshPinAnalogOutput
|
||||
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
void jshSetOutputValue(JshPinFunction func, int value) {
|
||||
jsiConsolePrintf("ESP8266: jshSetOutputValue %d %d\n", func, value);
|
||||
} // End of jshSetOutputValue
|
||||
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
void jshEnableWatchDog(JsVarFloat timeout) {
|
||||
jsiConsolePrintf("ESP8266: jshEnableWatchDog %0.3f\n", timeout);
|
||||
} // End of jshEnableWatchDog
|
||||
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
bool jshGetWatchedPinState(IOEventFlags device) {
|
||||
jsiConsolePrintf("ESP8266: jshGetWatchedPinState %d", device);
|
||||
return false;
|
||||
@ -370,12 +428,21 @@ void jshPinPulse(Pin pin, //!< The pin to be pulsed.
|
||||
} // End of jshPinPulse
|
||||
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
bool jshCanWatch(Pin pin) {
|
||||
return false;
|
||||
} // End of jshCanWatch
|
||||
|
||||
|
||||
IOEventFlags jshPinWatch(Pin pin, bool shouldWatch) {
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
IOEventFlags jshPinWatch(
|
||||
Pin pin, //!< Unknown
|
||||
bool shouldWatch //!< Unknown
|
||||
) {
|
||||
if (jshIsPinValid(pin)) {
|
||||
} else
|
||||
jsError("Invalid pin!");
|
||||
@ -383,17 +450,25 @@ IOEventFlags jshPinWatch(Pin pin, bool shouldWatch) {
|
||||
} // End of jshPinWatch
|
||||
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
JshPinFunction jshGetCurrentPinFunction(Pin pin) {
|
||||
//os_printf("jshGetCurrentPinFunction %d\n", pin);
|
||||
return JSH_NOTHING;
|
||||
} // End of jshGetCurrentPinFunction
|
||||
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
bool jshIsEventForPin(IOEvent *event, Pin pin) {
|
||||
return IOEVENTFLAGS_GETTYPE(event->flags) == pinToEVEXTI(pin);
|
||||
} // End of jshIsEventForPin
|
||||
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
void jshUSARTSetup(IOEventFlags device, JshUSARTInfo *inf) {
|
||||
} // End of jshUSARTSetup
|
||||
|
||||
@ -407,39 +482,76 @@ void jshUSARTKick(IOEventFlags device) {
|
||||
esp8266_uartTransmitAll(device);
|
||||
} // End of jshUSARTKick
|
||||
|
||||
void jshSPISetup(IOEventFlags device, JshSPIInfo *inf) {
|
||||
|
||||
/**
|
||||
* \brief Unknown
|
||||
*
|
||||
*/
|
||||
void jshSPISetup(
|
||||
IOEventFlags device, //!< Unknown
|
||||
JshSPIInfo *inf //!< Unknown
|
||||
) {
|
||||
os_printf("ESP8266: jshSPISetup: device=%d, inf=0x%x\n", device, (int)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) {
|
||||
int jshSPISend(
|
||||
IOEventFlags device, //!< Unknown
|
||||
int data //!< Unknown
|
||||
) {
|
||||
os_printf("ESP8266: jshSPISend\n");
|
||||
return NAN;
|
||||
} // End of jshSPISend
|
||||
|
||||
/** Send 16 bit data through the given SPI device. */
|
||||
void jshSPISend16(IOEventFlags device, int data) {
|
||||
|
||||
/**
|
||||
\brief * Send 16 bit data through the given SPI device.
|
||||
*/
|
||||
void jshSPISend16(
|
||||
IOEventFlags device, //!< Unknown
|
||||
int data //!< Unknown
|
||||
) {
|
||||
os_printf("ESP8266: jshSPISend16\n");
|
||||
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) {
|
||||
|
||||
/**
|
||||
* \brief Set whether to send 16 bits or 8 over SPI.
|
||||
*/
|
||||
void jshSPISet16(
|
||||
IOEventFlags device, //!< Unknown
|
||||
bool is16 //!< Unknown
|
||||
) {
|
||||
os_printf("ESP8266: jshSPISet16\n");
|
||||
} // End of jshSPISet16
|
||||
|
||||
/** Wait until SPI send is finished, */
|
||||
void jshSPIWait(IOEventFlags device) {
|
||||
|
||||
/**
|
||||
* \brief Wait until SPI send is finished.
|
||||
*/
|
||||
void jshSPIWait(
|
||||
IOEventFlags device //!< Unknown
|
||||
) {
|
||||
os_printf("ESP8266: jshSPIWait\n");
|
||||
} // End of jshSPIWait
|
||||
|
||||
void jshI2CSetup(IOEventFlags device, JshI2CInfo *inf) {
|
||||
os_printf("ESP8266: jshI2CSetup\n");
|
||||
} // End of jshI2CSetup
|
||||
|
||||
void jshI2CWrite(IOEventFlags device, unsigned char address, int nBytes,
|
||||
const unsigned char *data, bool sendStop) {
|
||||
os_printf("ESP8266: jshI2CWrite\n");
|
||||
} // End of jshI2CWrite
|
||||
|
||||
void jshI2CRead(IOEventFlags device, unsigned char address, int nBytes,
|
||||
unsigned char *data, bool sendStop) {
|
||||
os_printf("ESP8266: jshI2CRead\n");
|
||||
} // End of jshI2CRead
|
||||
|
||||
/**
|
||||
|
||||
@ -779,13 +779,13 @@ UART_SetPrintPort(uint8 uart_no)
|
||||
{
|
||||
if(uart_no==1){
|
||||
os_install_putc1(uart1_write_char);
|
||||
}else{
|
||||
} 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);
|
||||
/*option 2: wait for a while if uart fifo is full*/
|
||||
os_install_putc1(uart0_write_char);
|
||||
}
|
||||
}
|
||||
} // End of UART_SetPrintPort
|
||||
|
||||
|
||||
//========================================================
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user