diff --git a/Makefile b/Makefile index 42b99f1de..ce15cff69 100644 --- a/Makefile +++ b/Makefile @@ -239,6 +239,9 @@ ifeq ($(BOARD), arduino_101) @echo "CONFIG_ROM_SIZE=$(ROM)" >> prj.conf @printf "CONFIG_SS_RESET_VECTOR=0x400%x\n" $$((($(ROM) + 64) * 1024)) >> prj.conf endif +ifeq ($(BOARD), frdm_k64f) + @cat fragments/prj.conf.frdm_k64f >> prj.conf +endif endif # Append script specific modules to prj.conf @if [ -e prj.conf.tmp ]; then \ diff --git a/fragments/prj.conf.frdm_k64f b/fragments/prj.conf.frdm_k64f new file mode 100644 index 000000000..f67882190 --- /dev/null +++ b/fragments/prj.conf.frdm_k64f @@ -0,0 +1 @@ +CONFIG_PINMUX_MCUX_PORTD=y diff --git a/samples/ButtonLEDs-k64f.js b/samples/ButtonLEDs-k64f.js index 5ea5a7882..8d86825ed 100644 --- a/samples/ButtonLEDs-k64f.js +++ b/samples/ButtonLEDs-k64f.js @@ -1,4 +1,4 @@ -// Copyright (c) 2016, Intel Corporation. +// Copyright (c) 2016-2017, Intel Corporation. // Test code for FRDM-K64F that uses the onboard RGB LED for output, and // onboard input button SW2. Blinks the LEDs on and off together, but when the @@ -11,12 +11,15 @@ console.log("GPIO test with two LEDs and a button..."); var gpio = require("gpio"); var pins = require("k64f_pins"); -// D0 - D13 will also work as these output pins, if you hook up an LED -var pinA = gpio.open({ pin: pins.LEDR }); -var pinB = gpio.open({ pin: pins.LEDB }); + +// D0 - D15 will also work as these output pins, if you hook up an LED +// (except D8 currently not working on Rev E3 board at least) +var ledr = gpio.open({pin: pins.LEDR}); +var ledb = gpio.open({pin: pins.LEDB}); // D0 - D15 will also work as this input pin, if you hook up a button -var pinIn = gpio.open({ pin: pins.SW2, direction: 'in', edge: 'falling' }); +// (except D8 currently not working on Rev E3 board at least) +var pinIn = gpio.open({pin: pins.SW2, direction: 'in', edge: 'falling'}); // tick is the delay between blinks var tick = 1000, toggle = false; @@ -24,11 +27,11 @@ var tick = 1000, toggle = false; setInterval(function () { toggle = !toggle; pinIn.read(); - pinA.write(toggle); - pinB.write(toggle); + ledr.write(toggle); + ledb.write(toggle); }, tick); pinIn.onchange = function(event) { - pinA.write(true); - pinB.write(false); + ledr.write(true); + ledb.write(false); }; diff --git a/samples/tests/GPIOInputs-k64f.js b/samples/tests/GPIOInputs-k64f.js new file mode 100644 index 000000000..e824f8df2 --- /dev/null +++ b/samples/tests/GPIOInputs-k64f.js @@ -0,0 +1,41 @@ +// Copyright (c) 2017, Intel Corporation. + +// Test code for FRDM-K64F that listens on pins D1-D15 as inputs and prints a +// message whenever one changes. Blinks D0 indefinitely, so you connect a +// jumper wire from D0 to each of the other pins (one at a time) and see which +// ones generate a console message. + +console.log("Test external GPIOs as inputs..."); + +console.log("\nWire D0 to each of D1-D15 in turn!"); +console.log("(D14-D15 are at the end of the 10-pin header)\n"); + +// Expected results: All pins but D8 currently show up with input events + +// import gpio module +var gpio = require("gpio"); +var pins = require("k64f_pins"); + +// blink D0 forever +var tick = 250, toggle = false; +var output = gpio.open({pin: pins.D0}); +setInterval(function () { + output.write(toggle); + toggle = !toggle; +}, tick); + +// test all pins but D0 +var testpins = [pins.D1, pins.D2, pins.D3, pins.D4, pins.D5, pins.D6, pins.D7, + pins.D8, pins.D9, pins.D10, pins.D11, pins.D12, pins.D13, + pins.D14, pins.D15]; +var pincount = testpins.length; + +var count = 1; +var gpios = []; +for (var i = 0; i < pincount; i++) { + gpios[i] = gpio.open({pin: testpins[i], direction: 'in', edge: 'rising'}); + gpios[i].onchange = function(event) { + console.log("Input event", count); + count++; + } +} diff --git a/samples/tests/GPIOOutputs-k64f.js b/samples/tests/GPIOOutputs-k64f.js new file mode 100644 index 000000000..bae5fe73a --- /dev/null +++ b/samples/tests/GPIOOutputs-k64f.js @@ -0,0 +1,43 @@ +// Copyright (c) 2017, Intel Corporation. + +// Test code for FRDM-K64F that toggles each of pins D1-D15 as outputs +// indefinitely. Configures D0 as an input and prints a message whenever it +// changes, so you connect a jumper wire from D0 to each of the other pins (one +// at a time) and see which ones generate a console message. + +console.log("Test external GPIOs as outputs..."); + +console.log("\nWire D0 to each of D1-D15 in turn!"); +console.log("(D14-D15 are at the end of the 10-pin header)\n"); + +// Expected results: All pins but D8 currently show up with output events + +// import gpio module +var gpio = require("gpio"); +var pins = require("k64f_pins"); + +// blink D0 forever +var input = gpio.open({pin: pins.D0, direction: 'in', edge: 'rising'}); +var count = 1; +input.onchange = function(event) { + console.log("Output event", count); + count++; +} + +// test all pins but D0 +var testpins = [pins.D1, pins.D2, pins.D3, pins.D4, pins.D5, pins.D6, pins.D7, + pins.D8, pins.D9, pins.D10, pins.D11, pins.D12, pins.D13, + pins.D14, pins.D15]; +var pincount = testpins.length; +var gpios = []; +for (var i = 0; i < pincount; i++) { + gpios[i] = gpio.open({pin: testpins[i]}); +} + +var tick = 250, toggle = false; +setInterval(function () { + for (var i = 0; i < pincount; i++) { + gpios[i].write(toggle); + } + toggle = !toggle; +}, tick); diff --git a/src/Makefile.base b/src/Makefile.base index 96cba60c1..19d7a8b6a 100644 --- a/src/Makefile.base +++ b/src/Makefile.base @@ -78,7 +78,8 @@ obj-$(CONFIG_BOARD_ARDUINO_101) += \ zjs_ipm.o obj-$(CONFIG_BOARD_FRDM_K64F) += \ - zjs_k64f_pins.o + zjs_k64f_pins.o \ + zjs_pinmux.o ifeq ($(ASHELL), y) $(info Insecure Mode (development)) diff --git a/src/zjs_gpio.c b/src/zjs_gpio.c index 610841b4a..e11166772 100644 --- a/src/zjs_gpio.c +++ b/src/zjs_gpio.c @@ -114,10 +114,14 @@ static void zjs_gpio_c_callback(void *h, const void *args) // If pin.onChange exists, call it if (jerry_value_is_function(onchange_func)) { ZVAL event = jerry_create_object(); - uint32_t val = 0; - memcpy(&val, args, 4); + uint32_t *the_args = (uint32_t *)args; // Put the boolean GPIO trigger value in the object - zjs_obj_add_boolean(event, val, "value"); + zjs_obj_add_boolean(event, the_args[0], "value"); + zjs_obj_add_number(event, the_args[1], "pins"); + // TODO: This "pins" value is pretty useless to the JS script as is, + // because it is a bitmask of activated zephyr pins; need to map this + // back to JS pin values somehow. So leaving undocumented for now. + // This is more complex on k64f because of five GPIO ports. // Call the JS callback jerry_call_function(onchange_func, ZJS_UNDEFINED, &event, 1); @@ -138,9 +142,9 @@ static void zjs_gpio_zephyr_callback(struct device *port, gpio_pin_read(port, handle->pin, &handle->value); if ((handle->edge_both && handle->value != handle->last) || !handle->edge_both) { + uint32_t args[] = {handle->value, pins}; // Signal the C callback, where we call the JS callback - zjs_signal_callback(handle->callbackId, &handle->value, - sizeof(handle->value)); + zjs_signal_callback(handle->callbackId, args, sizeof(args)); handle->last = handle->value; } } diff --git a/src/zjs_k64f_pins.c b/src/zjs_k64f_pins.c index e892de4b9..3c2239d90 100644 --- a/src/zjs_k64f_pins.c +++ b/src/zjs_k64f_pins.c @@ -1,4 +1,4 @@ -// Copyright (c) 2016, Intel Corporation. +// Copyright (c) 2016-2017, Intel Corporation. // Zephyr includes #include @@ -52,19 +52,22 @@ jerry_value_t zjs_k64f_init() zjs_obj_add_number(obj, PTC + 16, "D0"); // verified I/O zjs_obj_add_number(obj, PTC + 17, "D1"); // verified I/O zjs_obj_add_number(obj, PTB + 9, "D2"); // verified I/O - zjs_obj_add_number(obj, PTA + 1, "D3"); // I/O if preserve jtag off + zjs_obj_add_number(obj, PTA + 1, "D3"); // verified I/O zjs_obj_add_number(obj, PTB + 23, "D4"); // verified I/O - zjs_obj_add_number(obj, PTA + 2, "D5"); // I/O if preserve jtag off + zjs_obj_add_number(obj, PTA + 2, "D5"); // verified I/O zjs_obj_add_number(obj, PTC + 2, "D6"); // verified I/O zjs_obj_add_number(obj, PTC + 3, "D7"); // verified I/O - zjs_obj_add_number(obj, PTC + 12, "D8"); // PTA0 for Rev <= D (ver. I/O) + + // currently not working on rev E3; used to work as input/output + zjs_obj_add_number(obj, PTC + 12, "D8"); // PTA0 for Rev <= D + zjs_obj_add_number(obj, PTC + 4, "D9"); // verified I/O zjs_obj_add_number(obj, PTD + 0, "D10"); // verified I/O zjs_obj_add_number(obj, PTD + 2, "D11"); // verified I/O zjs_obj_add_number(obj, PTD + 3, "D12"); // verified I/O zjs_obj_add_number(obj, PTD + 1, "D13"); // verified I/O - zjs_obj_add_number(obj, PTE + 25, "D14"); // works as input, not output - zjs_obj_add_number(obj, PTE + 24, "D15"); // works as input, not output + zjs_obj_add_number(obj, PTE + 25, "D14"); // verified I/O + zjs_obj_add_number(obj, PTE + 24, "D15"); // verified I/O // These are for onboard RGB LED zjs_obj_add_number(obj, PTB + 22, "LEDR"); // verified diff --git a/src/zjs_pinmux.c b/src/zjs_pinmux.c new file mode 100644 index 000000000..6b65a58c3 --- /dev/null +++ b/src/zjs_pinmux.c @@ -0,0 +1,55 @@ +// Copyright (c) 2017, Intel Corporation. + +// This file is currently meant only for FRDM_K64F board + +// C includes +#include + +// Zephyr includes +#include +#include +#include +#include +#include + +// CONFIG_INIT_PINMUX_PRIORITY + 1 to override default pinmux settings +#define CONFIG_K64F_PINMUX_PRIORITY 46 + +int frdm_k64f_pinmux_setup(struct device *unused) +{ + // NOTE: Here we enable all the controllers but in a real design you would + // probably try to optimize for the minimum number of GPIO controllers + // turned on to save power. See zephyr/boards/arm/frdm_k64f/pinmux.c for + // defaults. + + // TODO: eventually we maybe need to analyze script to decide how to do + // pinmux, or have user provide a static configuration + struct device *porta = device_get_binding(CONFIG_PINMUX_MCUX_PORTA_NAME); + pinmux_pin_set(porta, 0, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(porta, 1, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(porta, 2, PORT_PCR_MUX(kPORT_MuxAsGpio)); + + struct device *portb = device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME); + pinmux_pin_set(portb, 9, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(portb, 23, PORT_PCR_MUX(kPORT_MuxAsGpio)); + + struct device *portc = device_get_binding(CONFIG_PINMUX_MCUX_PORTC_NAME); + pinmux_pin_set(portc, 2, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(portc, 3, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(portc, 4, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(portc, 16, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(portc, 17, PORT_PCR_MUX(kPORT_MuxAsGpio)); + + struct device *portd = device_get_binding(CONFIG_PINMUX_MCUX_PORTD_NAME); + pinmux_pin_set(portd, 0, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(portd, 1, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(portd, 2, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(portd, 3, PORT_PCR_MUX(kPORT_MuxAsGpio)); + + struct device *porte = device_get_binding(CONFIG_PINMUX_MCUX_PORTE_NAME); + pinmux_pin_set(porte, 25, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(porte, 24, PORT_PCR_MUX(kPORT_MuxAsGpio)); + return 0; +} + +SYS_INIT(frdm_k64f_pinmux_setup, POST_KERNEL, CONFIG_K64F_PINMUX_PRIORITY);