Code changes for SPI testing.

See #588
This commit is contained in:
Neil Kolban 2015-09-29 17:13:57 -05:00
parent 07aac1cc11
commit 908ed13cf6
16 changed files with 843 additions and 415 deletions

View File

@ -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
View File

@ -0,0 +1,2 @@
/html/
/latex/

View File

@ -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());

View File

@ -28,6 +28,7 @@
*
*/
// ESP8266 specific includes
#define ESPSDK_1_3_0
#include <c_types.h>
#include <user_interface.h>
#include <mem.h>

View File

@ -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);

View File

@ -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) {

View File

@ -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");
}

View File

@ -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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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();

View File

@ -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
/**

View File

@ -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
//========================================================