void jswrap_onewire_write(JsVar *parent, JsVar *data, bool leavePowerOn) { Pin pin = onewire_getpin(parent); if (!jshIsPinValid(pin)) return; jsvIterateCallback(data, (void (*)(int, void *))_jswrap_onewire_write_cb, (void*)&pin); if (leavePowerOn) { // We're asked to leave power on for parasitically powered devices, to do that properly we // need to actively pull the line high. This is required, for example, for parasitically // powered DS18B20 temperature sensors. jshPinSetValue(pin, 1); jshPinSetState(pin, JSHPINSTATE_GPIO_OUT); } else { // We don't need to leave power on, so just tri-state the pin jshPinSetState(pin, JSHPINSTATE_GPIO_IN); jshPinSetValue(pin, 1); } }
/*JSON{ "type" : "method", "class" : "OneWire", "name" : "read", "generate" : "jswrap_onewire_read", "params" : [["count","JsVar","(optional) The amount of bytes to read"]], "return" : ["JsVar","The byte that was read, or a Uint8Array if count was specified and >=0"] } Read a byte */ JsVar *jswrap_onewire_read(JsVar *parent, JsVar *count) { Pin pin = onewire_getpin(parent); if (!jshIsPinValid(pin)) return 0; if (jsvIsNumeric(count)) { JsVarInt c = jsvGetInteger(count); JsVar *arr = jsvNewTypedArray(ARRAYBUFFERVIEW_UINT8, c); if (!arr) return 0; JsvArrayBufferIterator it; jsvArrayBufferIteratorNew(&it, arr, 0); while (c--) { jsvArrayBufferIteratorSetByteValue(&it, (char)OneWireRead(pin, 8)); jsvArrayBufferIteratorNext(&it); } jsvArrayBufferIteratorFree(&it); return arr; } else { return jsvNewFromInteger(OneWireRead(pin, 8)); } }
void jshPinWatch(Pin pin, bool shouldWatch) { if (jshIsPinValid(pin)) { #ifdef SYSFS_GPIO_DIR IOEventFlags exti = getNewEVEXTI(); if (shouldWatch) { if (exti) { gpioShouldWatch[pin] = true; gpioEventFlags[pin] = exti; jshPinSetState(pin, JSHPINSTATE_GPIO_IN); gpioLastState[pin] = jshPinGetValue(pin); } else jsError("You can only have a maximum of 16 watches!"); } if (!shouldWatch || !exti) { gpioShouldWatch[pin] = false; gpioEventFlags[pin] = 0; } #endif } else jsError("Invalid pin!"); }
void jshPinPulse(Pin pin, bool pulsePolarity, JsVarFloat pulseTime) { // ---- USE TIMER FOR PULSE if (!jshIsPinValid(pin)) { jsExceptionHere(JSET_ERROR, "Invalid pin!"); return; } if (pulseTime<=0) { // just wait for everything to complete jstUtilTimerWaitEmpty(); return; } else { // find out if we already had a timer scheduled UtilTimerTask task; if (!jstGetLastPinTimerTask(pin, &task)) { // no timer - just start the pulse now! jshPinOutput(pin, pulsePolarity); task.time = jshGetSystemTime(); } // Now set the end of the pulse to happen on a timer jstPinOutputAtTime(task.time + jshGetTimeFromMilliseconds(pulseTime), &pin, 1, !pulsePolarity); } }
IOEventFlags jshPinWatch(Pin pin, bool shouldWatch) { if (jshIsPinValid(pin)) { } else jsError("Invalid pin!"); return EV_NONE; } // End of jshPinWatch
/*JSON{ "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."] ], "return" : ["JsVar","A Pin object"] } Creates a pin from the given argument (or returns undefined if no argument) */ JsVar *jswrap_pin_constructor(JsVar *val) { Pin pin = jshGetPinFromVar(val); if (!jshIsPinValid(pin)) return 0; return jsvNewFromPin(pin); }
/** Write the pin name to a string. String must have at least 8 characters (to be safe) */ void jshGetPinString(char *result, Pin pin) { result[0] = 0; // just in case #ifdef PIN_NAMES_DIRECT if (jshIsPinValid(pin)) { result[0]='A'+pinInfo[pin].port-JSH_PORTA; itostr(pinInfo[pin].pin-JSH_PIN0,&result[1],10); #else if ( #if JSH_PORTA_OFFSET!=0 pin>=JSH_PORTA_OFFSET && #endif pin<JSH_PORTA_OFFSET+JSH_PORTA_COUNT) { result[0]='A'; itostr(pin-JSH_PORTA_OFFSET,&result[1],10); } else if (pin>=JSH_PORTB_OFFSET && pin<JSH_PORTB_OFFSET+JSH_PORTB_COUNT) { result[0]='B'; itostr(pin-JSH_PORTB_OFFSET,&result[1],10); } else if (pin>=JSH_PORTC_OFFSET && pin<JSH_PORTC_OFFSET+JSH_PORTC_COUNT) { result[0]='C'; itostr(pin-JSH_PORTC_OFFSET,&result[1],10); } else if (pin>=JSH_PORTD_OFFSET && pin<JSH_PORTD_OFFSET+JSH_PORTD_COUNT) { result[0]='D'; itostr(pin-JSH_PORTD_OFFSET,&result[1],10); #if JSH_PORTE_OFFSET!=-1 } else if (pin>=JSH_PORTE_OFFSET && pin<JSH_PORTE_OFFSET+JSH_PORTE_COUNT) { result[0]='E'; itostr(pin-JSH_PORTE_OFFSET,&result[1],10); #endif #if JSH_PORTF_OFFSET!=-1 } else if (pin>=JSH_PORTF_OFFSET && pin<JSH_PORTF_OFFSET+JSH_PORTF_COUNT) { result[0]='F'; itostr(pin-JSH_PORTF_OFFSET,&result[1],10); #endif #if JSH_PORTG_OFFSET!=-1 } else if (pin>=JSH_PORTG_OFFSET && pin<JSH_PORTG_OFFSET+JSH_PORTG_COUNT) { result[0]='G'; itostr(pin-JSH_PORTG_OFFSET,&result[1],10); #endif #if JSH_PORTH_OFFSET!=-1 } else if (pin>=JSH_PORTH_OFFSET && pin<JSH_PORTH_OFFSET+JSH_PORTH_COUNT) { result[0]='H'; itostr(pin-JSH_PORTH_OFFSET,&result[1],10); #endif #endif } else { strncpy(result, "UNKNOWN", 8); } } /// 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; } Pin jshGetPinFromVarAndUnLock(JsVar *pinv) { Pin pin = jshGetPinFromVar(pinv); jsvUnLock(pinv); return pin; }
void jshPinOutput(Pin pin, bool value) { if (jshIsPinValid(pin)) jshPinSetValue(pin, value); }
bool jshPinInput(Pin pin) { if (jshIsPinValid(pin)) return jshPinGetValue(pin); return false; }
/*JSON{ "type" : "method", "class" : "OneWire", "name" : "search", "generate" : "jswrap_onewire_search", "params" : [ ["command","int32","(Optional) command byte. If not specified (or zero), this defaults to 0xF0. This can could be set to 0xEC to perform a DS18B20 'Alarm Search Command'"] ], "return" : ["JsVar","An array of devices that were found"] } Search for devices */ JsVar *jswrap_onewire_search(JsVar *parent, int command) { // search - code from http://www.maximintegrated.com/app-notes/index.mvp/id/187 Pin pin = onewire_getpin(parent); if (!jshIsPinValid(pin)) return 0; JsVar *array = jsvNewEmptyArray(); if (!array) return 0; if (command<=0 || command>255) command = 0xF0; // normal search command // global search state unsigned char ROM_NO[8]; int LastDiscrepancy; int LastFamilyDiscrepancy; int LastDeviceFlag; // reset the search state LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; int search_result = true; while (search_result) { int id_bit_number; int last_zero, rom_byte_number; unsigned char id_bit, cmp_id_bit; unsigned char rom_byte_mask, search_direction; // initialize for search id_bit_number = 1; last_zero = 0; rom_byte_number = 0; rom_byte_mask = 1; search_result = 0; // if the last call was not the last one if (!LastDeviceFlag) { // 1-Wire reset if (!OneWireReset(pin)) { // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return array; } // issue the search command OneWireWrite(pin, 8, (unsigned long long)command); // loop to do the search do { // read a bit and its complement id_bit = (unsigned char)OneWireRead(pin, 1); cmp_id_bit = (unsigned char)OneWireRead(pin, 1); // check for no devices on 1-wire if ((id_bit == 1) && (cmp_id_bit == 1)) break; else { // all devices coupled have 0 or 1 if (id_bit != cmp_id_bit) search_direction = id_bit; // bit write value for search else { // if this discrepancy if before the Last Discrepancy // on a previous next then pick the same as last time if (id_bit_number < LastDiscrepancy) search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); else // if equal to last pick 1, if not then pick 0 search_direction = (id_bit_number == LastDiscrepancy); // if 0 was picked then record its position in LastZero if (search_direction == 0) { last_zero = id_bit_number; // check for Last discrepancy in family if (last_zero < 9) LastFamilyDiscrepancy = last_zero; } } // set or clear the bit in the ROM byte rom_byte_number // with mask rom_byte_mask if (search_direction == 1) ROM_NO[rom_byte_number] |= rom_byte_mask; else ROM_NO[rom_byte_number] &= (unsigned char)~rom_byte_mask; // serial number search direction write bit OneWireWrite(pin, 1, search_direction); // increment the byte counter id_bit_number // and shift the mask rom_byte_mask id_bit_number++; rom_byte_mask = (unsigned char)(rom_byte_mask << 1); // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask if (rom_byte_mask == 0) { rom_byte_number++; rom_byte_mask = 1; } } } while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 // if the search was successful then if (!((id_bit_number < 65))) { // search successful so set LastDiscrepancy,LastDeviceFlag,search_result LastDiscrepancy = last_zero; // check for last device if (LastDiscrepancy == 0) LastDeviceFlag = TRUE; search_result = TRUE; } } // if no device found then reset counters so next 'search' will be like a first if (!search_result || !ROM_NO[0]) { LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; search_result = FALSE; } if (search_result) { int i; char buf[17]; for (i=0;i<8;i++) { buf[i*2] = itoch((ROM_NO[i]>>4) & 15); buf[i*2+1] = itoch(ROM_NO[i] & 15); } buf[16]=0; jsvArrayPushAndUnLock(array, jsvNewFromString(buf)); } NOT_USED(LastFamilyDiscrepancy); } return array; }
/*JSON{ "type" : "method", "class" : "OneWire", "name" : "skip", "generate" : "jswrap_onewire_skip" } Skip a ROM */ void jswrap_onewire_skip(JsVar *parent) { Pin pin = onewire_getpin(parent); if (!jshIsPinValid(pin)) return; OneWireWrite(pin, 8, 0xCC); }
/*JSON{ "type" : "method", "class" : "OneWire", "name" : "reset", "generate" : "jswrap_onewire_reset", "return" : ["bool","True is a device was present (it held the bus low)"] } Perform a reset cycle */ bool jswrap_onewire_reset(JsVar *parent) { Pin pin = onewire_getpin(parent); if (!jshIsPinValid(pin)) return 0; return OneWireReset(pin); }
/*JSON{ "type" : "staticmethod", "class" : "WIZnet", "name" : "connect", "generate" : "jswrap_wiznet_connect", "params" : [ ["spi", "JsVar", "Device to use for SPI (or undefined to use the default)"], ["cs", "pin", "The pin to use for Chip Select"] ], "return" : ["JsVar","An Ethernet Object"], "return_object" : "Ethernet" } Initialise the WIZnet module and return an Ethernet object */ JsVar *jswrap_wiznet_connect(JsVar *spi, Pin cs) { IOEventFlags spiDevice; if (spi) { spiDevice = jsiGetDeviceFromClass(spi); if (!DEVICE_IS_SPI(spiDevice)) { jsExceptionHere(JSET_ERROR, "Expecting SPI device, got %q", spi); return 0; } } else { // SPI config JshSPIInfo inf; jshSPIInitInfo(&inf); inf.pinSCK = ETH_CLK_PIN; inf.pinMISO = ETH_MISO_PIN; inf.pinMOSI = ETH_MOSI_PIN; inf.baudRate = 1000000; inf.spiMode = SPIF_SPI_MODE_0; jshSPISetup(ETH_SPI, &inf); spiDevice = ETH_SPI; } if (!jshIsPinValid(cs)) cs = ETH_CS_PIN; JsNetwork net; networkCreate(&net, JSNETWORKTYPE_W5500); net.data.device = spiDevice; net.data.pinCS = cs; networkSet(&net); JsVar *ethObj = jspNewObject(0, "Ethernet"); // CS Configuration jshSetPinStateIsManual(net.data.pinCS, false); jshPinOutput(net.data.pinCS, 1); // de-assert CS // Initialise WIZnet functions reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect); reg_wizchip_spi_cbfunc(wizchip_read, wizchip_write); /* wizchip initialize*/ uint8_t tmp; uint8_t memsize[2][8] = { {2,2,2,2,2,2,2,2}, {2,2,2,2,2,2,2,2}}; if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1) { jsiConsolePrint("WIZnet Initialize failed.\r\n"); networkFree(&net); return 0; } #if _WIZCHIP_ == 5500 /* PHY link status check - W5100 doesn't have this */ do { if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1) { jsiConsolePrint("Unknown PHY Link status.\r\n"); networkFree(&net); return 0; } } while (tmp == PHY_LINK_OFF); #endif networkFree(&net); networkState = NETWORKSTATE_ONLINE; return ethObj; }
void jshPinWatch(Pin pin, bool shouldWatch) { if (jshIsPinValid(pin)) { } else jsError("Invalid pin!"); }
void jshPinOutput(Pin pin, bool value) { if (jshIsPinValid(pin)) { jshPinSetState(pin, JSHPINSTATE_GPIO_OUT); jshPinSetValue(pin, value); } else jsError("Invalid pin!"); }