From ee889f49f76c73cb4e9d0b8bae606e868cb4c6ba Mon Sep 17 00:00:00 2001 From: Geoff Gustafson Date: Fri, 31 Mar 2017 09:31:19 -0700 Subject: [PATCH 1/2] [k64f] Restore GPIO functionality by enabling pins via pinmux Zephyr defaults changed around January for this board to no longer set GPIO as default pinmux state for any of the external pins. So we need to override them ourselves. Eventually we may need to get fancier to set pinmux based on what the user's script wants to use the pins for, or set up a default "ABI" for pinmux settings for the board. The pinmux must be set up at board initialization time apparently. Add new zjs_pinmux.c (currently for k64f only) to configure the pinmux settings at initialization time. Add a new prj.conf to enable GPIO port "D". Add new samples GPIOInputs-k64.js and GPIOOutputs-k64.js to quickly demonstrate which pins are functional. With this update, pins D14 and D15 work as outputs for the first time. But pin D8 on my rev E3 board doesn't seem to work as either anymore. Fixes #514 and lets us finally see that #665 really was resolved. Signed-off-by: Geoff Gustafson --- Makefile | 3 ++ fragments/prj.conf.frdm_k64f | 1 + samples/ButtonLEDs-k64f.js | 21 +++++++----- samples/tests/GPIOInputs-k64f.js | 41 +++++++++++++++++++++++ samples/tests/GPIOOutputs-k64f.js | 43 ++++++++++++++++++++++++ src/Makefile.base | 3 +- src/zjs_gpio.c | 14 +++++--- src/zjs_k64f_pins.c | 15 +++++---- src/zjs_pinmux.c | 55 +++++++++++++++++++++++++++++++ 9 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 fragments/prj.conf.frdm_k64f create mode 100644 samples/tests/GPIOInputs-k64f.js create mode 100644 samples/tests/GPIOOutputs-k64f.js create mode 100644 src/zjs_pinmux.c 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..df7ccea6f --- /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..b4705a138 --- /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); From b4168538c3a526a2e3981c5116a5a4df2afef9ca Mon Sep 17 00:00:00 2001 From: Geoff Gustafson Date: Mon, 3 Apr 2017 12:39:07 -0700 Subject: [PATCH 2/2] added semi-colons Signed-off-by: Geoff Gustafson --- samples/tests/GPIOInputs-k64f.js | 2 +- samples/tests/GPIOOutputs-k64f.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/tests/GPIOInputs-k64f.js b/samples/tests/GPIOInputs-k64f.js index df7ccea6f..e824f8df2 100644 --- a/samples/tests/GPIOInputs-k64f.js +++ b/samples/tests/GPIOInputs-k64f.js @@ -31,7 +31,7 @@ var testpins = [pins.D1, pins.D2, pins.D3, pins.D4, pins.D5, pins.D6, pins.D7, var pincount = testpins.length; var count = 1; -var gpios = [] +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) { diff --git a/samples/tests/GPIOOutputs-k64f.js b/samples/tests/GPIOOutputs-k64f.js index b4705a138..bae5fe73a 100644 --- a/samples/tests/GPIOOutputs-k64f.js +++ b/samples/tests/GPIOOutputs-k64f.js @@ -29,7 +29,7 @@ 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 = [] +var gpios = []; for (var i = 0; i < pincount; i++) { gpios[i] = gpio.open({pin: testpins[i]}); }