/*JSON{ "type" : "method", "class" : "SPI", "name" : "setup", "generate" : "jswrap_spi_setup", "params" : [ ["options","JsVar",["An optional structure containing extra information on initialising the SPI port","Please note that baud rate is set to the nearest that can be managed - which may be -+ 50%","```{sck:pin, miso:pin, mosi:pin, baud:integer=100000, mode:integer=0, order:'msb'/'lsb'='msb' }```","If sck,miso and mosi are left out, they will automatically be chosen. However if one or more is specified then the unspecified pins will not be set up.","You can find out which pins to use by looking at [your board's reference page](#boards) and searching for pins with the `SPI` marker.","The SPI ```mode``` is between 0 and 3 - see http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Clock_polarity_and_phase","On STM32F1-based parts, you cannot mix AF and non-AF pins (SPI pins are usually grouped on the chip - and you can't mix pins from two groups). Espruino will not warn you about this."]] ] } Set up this SPI port as an SPI Master. */ void jswrap_spi_setup(JsVar *parent, JsVar *options) { IOEventFlags device = jsiGetDeviceFromClass(parent); JshSPIInfo inf; jsspiPopulateSPIInfo(&inf, options); if (DEVICE_IS_SPI(device)) { jshSPISetup(device, &inf); #ifdef LINUX if (jsvIsObject(options)) { jsvUnLock(jsvObjectSetChild(parent, "path", jsvObjectGetChild(options, "path", 0))); } #endif } else if (device == EV_NONE) { // software mode - at least configure pins properly if (inf.pinSCK != PIN_UNDEFINED) jshPinSetState(inf.pinSCK, JSHPINSTATE_GPIO_OUT); if (inf.pinMISO != PIN_UNDEFINED) jshPinSetState(inf.pinMISO, JSHPINSTATE_GPIO_IN); if (inf.pinMOSI != PIN_UNDEFINED) jshPinSetState(inf.pinMOSI, JSHPINSTATE_GPIO_OUT); } else return; // Set up options, so we can initialise it on startup if (options) jsvUnLock(jsvSetNamedChild(parent, options, DEVICE_OPTIONS_NAME)); else jsvRemoveNamedChild(parent, DEVICE_OPTIONS_NAME); }
IOEventFlags jshPinWatch(Pin pin, bool shouldWatch) { if (jshIsPinValid(pin)) { IOEventFlags exti = getNewEVEXTI(); if (shouldWatch) { if (exti) { gpioEventFlags[pin] = exti; jshPinSetState(pin, JSHPINSTATE_GPIO_IN); #ifdef SYSFS_GPIO_DIR gpioShouldWatch[pin] = true; gpioLastState[pin] = jshPinGetValue(pin); #endif #ifdef USE_WIRINGPI wiringPiISR(pin, INT_EDGE_BOTH, irqEXTIs[exti-EV_EXTI0]); #endif } else jsError("You can only have a maximum of 16 watches!"); } if (!shouldWatch || !exti) { gpioEventFlags[pin] = 0; #ifdef SYSFS_GPIO_DIR gpioShouldWatch[pin] = false; #endif #ifdef USE_WIRINGPI wiringPiISR(pin, INT_EDGE_BOTH, irqEXTIDoNothing); #endif } return shouldWatch ? exti : EV_NONE; } else jsError("Invalid pin!"); return EV_NONE; }
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!"); }
void jshPinPulse(Pin pin, bool value, JsVarFloat time) { if (jshIsPinValid(pin)) { jshPinSetState(pin, JSHPINSTATE_GPIO_OUT); jshPinSetValue(pin, value); usleep(time*1000000); jshPinSetValue(pin, !value); } else jsError("Invalid pin!"); }
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); } }
bool jshPinInput(Pin pin) { bool value = false; if (jshIsPinValid(pin)) { jshPinSetState(pin, JSHPINSTATE_GPIO_IN); value = jshPinGetValue(pin); } else jsError("Invalid pin!"); return value; }
void LCD_init_hardware() { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); /* Enable the FSMC Clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE , ENABLE); /* Enable the FSMC pins for LCD control */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_7 /*NE1*/ | GPIO_Pin_11/*RS*/; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_Init(GPIOE, &GPIO_InitStructure); FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; FSMC_NORSRAMTimingInitTypeDef p; p.FSMC_AddressSetupTime = 0x02; p.FSMC_AddressHoldTime = 0x00; p.FSMC_DataSetupTime = 0x05; p.FSMC_BusTurnAroundDuration = 0x00; p.FSMC_CLKDivision = 0x00; p.FSMC_DataLatency = 0x00; p.FSMC_AccessMode = FSMC_AccessMode_B; FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR; FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1; FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); /* Enable FSMC Bank1_SRAM Bank */ FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); // Toggle LCD reset pin #ifdef LCD_RESET jshPinSetState(LCD_RESET, JSHPINSTATE_GPIO_OUT); jshPinSetValue(LCD_RESET, 0); //RESET=0 LCD_DELAY(DELAY_LONG); jshPinSetValue(LCD_RESET, 1); //RESET=1 #endif }
bool jshPinInput(Pin pin) { 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; }
/*JSON{ "type" : "method", "class" : "SPI", "name" : "setup", "generate" : "jswrap_spi_setup", "params" : [ ["options","JsVar",["An optional structure containing extra information on initialising the SPI port","Please note that baud rate is set to the nearest that can be managed - which may be -+ 50%","```{sck:pin, miso:pin, mosi:pin, baud:integer=100000, mode:integer=0, order:'msb'/'lsb'='msb' }```","If sck,miso and mosi are left out, they will automatically be chosen. However if one or more is specified then the unspecified pins will not be set up.","You can find out which pins to use by looking at [your board's reference page](#boards) and searching for pins with the `SPI` marker.","The SPI ```mode``` is between 0 and 3 - see http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Clock_polarity_and_phase","On STM32F1-based parts, you cannot mix AF and non-AF pins (SPI pins are usually grouped on the chip - and you can't mix pins from two groups). Espruino will not warn you about this."]] ] } Set up this SPI port as an SPI Master. */ 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)) { jshSPISetup(device, &inf); #ifdef LINUX if (jsvIsObject(options)) { jsvObjectSetChildAndUnLock(parent, "path", jsvObjectGetChild(options, "path", 0)); } #endif } else if (device == EV_NONE) { // software mode - at least configure pins properly if (inf.pinSCK != PIN_UNDEFINED) jshPinSetState(inf.pinSCK, JSHPINSTATE_GPIO_OUT); if (inf.pinMISO != PIN_UNDEFINED) jshPinSetState(inf.pinMISO, JSHPINSTATE_GPIO_IN); if (inf.pinMOSI != PIN_UNDEFINED) jshPinSetState(inf.pinMOSI, JSHPINSTATE_GPIO_OUT); } else return; // Set up options, so we can initialise it on startup if (options) jsvUnLock(jsvSetNamedChild(parent, options, DEVICE_OPTIONS_NAME)); else jsvRemoveNamedChild(parent, DEVICE_OPTIONS_NAME); }
void jshPinWatch(Pin pin, bool shouldWatch) { if (jshIsPinValid(pin)) { #ifdef SYSFS_GPIO_DIR gpioShouldWatch[pin] = shouldWatch; if (shouldWatch) { jshPinSetState(pin, JSHPINSTATE_GPIO_IN); gpioLastState[pin] = jshPinGetValue(pin); } #endif } else jsError("Invalid pin!"); }
JshPinFunction jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq, JshAnalogOutputFlags flags) { // if freq<=0, the default is used #ifdef USE_WIRINGPI // todo pwmSetRange and pwmSetClock for freq? int v = (int)(value*1024); if (v<0) v=0; if (v>1023) v=1023; jshPinSetState(pin, JSHPINSTATE_AF_OUT); pwmWrite(pin, (int)(value*1024)); #endif return JSH_NOTHING; }
/** Reset one-wire, return true if a device was present */ static bool NO_INLINE OneWireReset(Pin pin) { jshPinSetState(pin, JSHPINSTATE_GPIO_OUT_OPENDRAIN_PULLUP); //jshInterruptOff(); jshPinSetValue(pin, 0); jshDelayMicroseconds(500); jshPinSetValue(pin, 1); jshDelayMicroseconds(80); bool hasDevice = !jshPinGetValue(pin); //jshInterruptOn(); jshDelayMicroseconds(420); return hasDevice; }
/** Reset any devices that could have been set up differently by JS code. * Called from jshReset */ void jshResetDevices() { unsigned int i; // Reset list of pins that were set manually jshResetPinStateIsManual(); // setup flow control for (i=0;i<sizeof(jshSerialDeviceStates) / sizeof(JshSerialDeviceState);i++) jshSerialDeviceStates[i] = SDS_NONE; jshSerialDeviceStates[TO_SERIAL_DEVICE_STATE(EV_USBSERIAL)] = SDS_FLOW_CONTROL_XON_XOFF; // reset callbacks for events for (i=EV_EXTI0;i<=EV_EXTI_MAX;i++) jshEventCallbacks[i-EV_EXTI0] = 0; // Reset pin state for button #ifdef BTN1_PININDEX #ifdef BTN1_PINSTATE jshSetPinStateIsManual(BTN1_PININDEX, true); // so subsequent reads don't overwrite the state jshPinSetState(BTN1_PININDEX, BTN1_PINSTATE); #else jshPinSetState(BTN1_PININDEX, JSHPINSTATE_GPIO_IN); #endif #endif }
JshPinFunction jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq, JshAnalogOutputFlags flags) { /* we set the bit field here so that if the user changes the pin state * later on, we can get rid of the IRQs */ if (!jshGetPinStateIsManual(pin)) { BITFIELD_SET(jshPinSoftPWM, pin, 0); jshPinSetState(pin, JSHPINSTATE_GPIO_OUT); } BITFIELD_SET(jshPinSoftPWM, pin, 1); if (freq<=0) freq=50; jstPinPWM(freq, value, pin); return JSH_NOTHING; } // if freq<=0, the default is used
/** * \brief Set the value of the pin to be the value supplied and then wait for * a given period and set the pin value again to be the opposite. */ void jshPinPulse(Pin pin, //!< The pin to be pulsed. bool value, //!< The value to be pulsed into the pin. JsVarFloat time //!< The period in milliseconds to hold the pin. ) { if (jshIsPinValid(pin)) { jshPinSetState(pin, JSHPINSTATE_GPIO_OUT); jshPinSetValue(pin, value); jshDelayMicroseconds(jshGetTimeFromMilliseconds(time)); jshPinSetValue(pin, !value); } else jsError("Invalid pin!"); } // End of jshPinPulse
ALWAYS_INLINE void tv_start_line_video() { uint32_t lineIdx; if (tvCurrentLine <= 313) { lineIdx = ((uint32_t)tvCurrentLine-(5+PAL_VBLANK)) ; } else { lineIdx = ((uint32_t)tvCurrentLine-(317+PAL_VBLANK)); } if (lineIdx<270) { lineIdx = lineIdx*tvHeight/270; jshPinSetState(tvPinVideo, JSHPINSTATE_AF_OUT); // re-enable output for SPI uint32_t lsize = tvWidth>>3/*bytes*/; dma_start((uint32_t)tvPixelPtr + lineIdx*lsize, lsize); }
/** Write 'bits' bits, and return what was read (to read, you must send all 1s) */ static JsVarInt NO_INLINE OneWireRead(Pin pin, int bits) { jshPinSetState(pin, JSHPINSTATE_GPIO_OUT_OPENDRAIN_PULLUP); JsVarInt result = 0; JsVarInt mask = 1; while (bits-- > 0) { jshInterruptOff(); jshPinSetValue(pin, 0); jshDelayMicroseconds(3); jshPinSetValue(pin, 1); jshDelayMicroseconds(10); // leave time to let it rise if (jshPinGetValue(pin)) result = result | mask; jshInterruptOn(); jshDelayMicroseconds(53); mask = mask << 1; } return result; }
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!"); }
/** Write 'bits' bits, and return what was read (to read, you must send all 1s) */ static void NO_INLINE OneWireWrite(Pin pin, int bits, unsigned long long data) { jshPinSetState(pin, JSHPINSTATE_GPIO_OUT_OPENDRAIN_PULLUP); unsigned long long mask = 1; while (bits-- > 0) { if (data & mask) { // short pulse jshInterruptOff(); jshPinSetValue(pin, 0); jshDelayMicroseconds(10); jshPinSetValue(pin, 1); jshInterruptOn(); jshDelayMicroseconds(55); } else { // long pulse jshInterruptOff(); jshPinSetValue(pin, 0); jshDelayMicroseconds(65); jshPinSetValue(pin, 1); jshInterruptOn(); jshDelayMicroseconds(5); } mask = mask << 1; } }
void SpiInit(void) { // SPI config JshSPIInfo inf; jshSPIInitInfo(&inf); inf.pinSCK = WLAN_CLK_PIN; inf.pinMISO = WLAN_MISO_PIN; inf.pinMOSI = WLAN_MOSI_PIN; inf.baudRate = 100000; // FIXME - just slow for debug inf.spiMode = SPIF_SPI_MODE_1; // Mode 1 CPOL= 0 CPHA= 1 jshSPISetup(WLAN_SPI, &inf); // WLAN CS, EN and WALN IRQ Configuration jshSetPinStateIsManual(WLAN_CS_PIN, false); jshPinOutput(WLAN_CS_PIN, 1); // de-assert CS jshSetPinStateIsManual(WLAN_EN_PIN, false); jshPinOutput(WLAN_EN_PIN, 0); // disable WLAN jshSetPinStateIsManual(WLAN_IRQ_PIN, true); jshPinSetState(WLAN_IRQ_PIN, JSHPINSTATE_GPIO_IN_PULLUP); // flip into read mode with pullup // wait a little (ensure that WLAN takes effect) jshDelayMicroseconds(500*1000); // force a 500ms delay! FIXME }
/** * Reset the Espruino environment. */ void jshReset() { jshResetDevices(); os_printf("> jshReset\n"); // Set all GPIO pins to be input with pull-up jshPinSetState(0, JSHPINSTATE_GPIO_IN_PULLUP); //jshPinSetState(2, JSHPINSTATE_GPIO_IN_PULLUP); // used for debug output jshPinSetState(4, JSHPINSTATE_GPIO_IN_PULLUP); jshPinSetState(5, JSHPINSTATE_GPIO_IN_PULLUP); jshPinSetState(12, JSHPINSTATE_GPIO_IN_PULLUP); jshPinSetState(13, JSHPINSTATE_GPIO_IN_PULLUP); jshPinSetState(14, JSHPINSTATE_GPIO_IN_PULLUP); jshPinSetState(15, JSHPINSTATE_GPIO_IN_PULLUP); g_spiInitialized = false; // Flag the hardware SPI interface as un-initialized. g_lastSPIRead = -1; extern void user_uart_init(void); // in user_main.c user_uart_init(); jswrap_ESP8266_wifi_reset(); // reset the wifi os_printf("< jshReset\n"); }
void jshPinOutput(Pin pin, bool value) { if (jshIsPinValid(pin)) { jshPinSetState(pin, JSHPINSTATE_GPIO_OUT); jshPinSetValue(pin, value); } else jsError("Invalid pin!"); }