Skip to content
This repository was archived by the owner on Aug 5, 2022. It is now read-only.

Commit 9e12add

Browse files
grgustafJimmy Huang
authored andcommitted
[k64f] Restore GPIO functionality by enabling pins via pinmux (#954)
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 <[email protected]>
1 parent ed04317 commit 9e12add

File tree

9 files changed

+175
-21
lines changed

9 files changed

+175
-21
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ ifeq ($(BOARD), arduino_101)
239239
@echo "CONFIG_ROM_SIZE=$(ROM)" >> prj.conf
240240
@printf "CONFIG_SS_RESET_VECTOR=0x400%x\n" $$((($(ROM) + 64) * 1024)) >> prj.conf
241241
endif
242+
ifeq ($(BOARD), frdm_k64f)
243+
@cat fragments/prj.conf.frdm_k64f >> prj.conf
244+
endif
242245
endif
243246
# Append script specific modules to prj.conf
244247
@if [ -e prj.conf.tmp ]; then \

fragments/prj.conf.frdm_k64f

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CONFIG_PINMUX_MCUX_PORTD=y

samples/ButtonLEDs-k64f.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2016, Intel Corporation.
1+
// Copyright (c) 2016-2017, Intel Corporation.
22

33
// Test code for FRDM-K64F that uses the onboard RGB LED for output, and
44
// onboard input button SW2. Blinks the LEDs on and off together, but when the
@@ -11,24 +11,27 @@ console.log("GPIO test with two LEDs and a button...");
1111
var gpio = require("gpio");
1212
var pins = require("k64f_pins");
1313

14-
// D0 - D13 will also work as these output pins, if you hook up an LED
15-
var pinA = gpio.open({ pin: pins.LEDR });
16-
var pinB = gpio.open({ pin: pins.LEDB });
14+
15+
// D0 - D15 will also work as these output pins, if you hook up an LED
16+
// (except D8 currently not working on Rev E3 board at least)
17+
var ledr = gpio.open({pin: pins.LEDR});
18+
var ledb = gpio.open({pin: pins.LEDB});
1719

1820
// D0 - D15 will also work as this input pin, if you hook up a button
19-
var pinIn = gpio.open({ pin: pins.SW2, direction: 'in', edge: 'falling' });
21+
// (except D8 currently not working on Rev E3 board at least)
22+
var pinIn = gpio.open({pin: pins.SW2, direction: 'in', edge: 'falling'});
2023

2124
// tick is the delay between blinks
2225
var tick = 1000, toggle = false;
2326

2427
setInterval(function () {
2528
toggle = !toggle;
2629
pinIn.read();
27-
pinA.write(toggle);
28-
pinB.write(toggle);
30+
ledr.write(toggle);
31+
ledb.write(toggle);
2932
}, tick);
3033

3134
pinIn.onchange = function(event) {
32-
pinA.write(true);
33-
pinB.write(false);
35+
ledr.write(true);
36+
ledb.write(false);
3437
};

samples/tests/GPIOInputs-k64f.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) 2017, Intel Corporation.
2+
3+
// Test code for FRDM-K64F that listens on pins D1-D15 as inputs and prints a
4+
// message whenever one changes. Blinks D0 indefinitely, so you connect a
5+
// jumper wire from D0 to each of the other pins (one at a time) and see which
6+
// ones generate a console message.
7+
8+
console.log("Test external GPIOs as inputs...");
9+
10+
console.log("\nWire D0 to each of D1-D15 in turn!");
11+
console.log("(D14-D15 are at the end of the 10-pin header)\n");
12+
13+
// Expected results: All pins but D8 currently show up with input events
14+
15+
// import gpio module
16+
var gpio = require("gpio");
17+
var pins = require("k64f_pins");
18+
19+
// blink D0 forever
20+
var tick = 250, toggle = false;
21+
var output = gpio.open({pin: pins.D0});
22+
setInterval(function () {
23+
output.write(toggle);
24+
toggle = !toggle;
25+
}, tick);
26+
27+
// test all pins but D0
28+
var testpins = [pins.D1, pins.D2, pins.D3, pins.D4, pins.D5, pins.D6, pins.D7,
29+
pins.D8, pins.D9, pins.D10, pins.D11, pins.D12, pins.D13,
30+
pins.D14, pins.D15];
31+
var pincount = testpins.length;
32+
33+
var count = 1;
34+
var gpios = [];
35+
for (var i = 0; i < pincount; i++) {
36+
gpios[i] = gpio.open({pin: testpins[i], direction: 'in', edge: 'rising'});
37+
gpios[i].onchange = function(event) {
38+
console.log("Input event", count);
39+
count++;
40+
}
41+
}

samples/tests/GPIOOutputs-k64f.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) 2017, Intel Corporation.
2+
3+
// Test code for FRDM-K64F that toggles each of pins D1-D15 as outputs
4+
// indefinitely. Configures D0 as an input and prints a message whenever it
5+
// changes, so you connect a jumper wire from D0 to each of the other pins (one
6+
// at a time) and see which ones generate a console message.
7+
8+
console.log("Test external GPIOs as outputs...");
9+
10+
console.log("\nWire D0 to each of D1-D15 in turn!");
11+
console.log("(D14-D15 are at the end of the 10-pin header)\n");
12+
13+
// Expected results: All pins but D8 currently show up with output events
14+
15+
// import gpio module
16+
var gpio = require("gpio");
17+
var pins = require("k64f_pins");
18+
19+
// blink D0 forever
20+
var input = gpio.open({pin: pins.D0, direction: 'in', edge: 'rising'});
21+
var count = 1;
22+
input.onchange = function(event) {
23+
console.log("Output event", count);
24+
count++;
25+
}
26+
27+
// test all pins but D0
28+
var testpins = [pins.D1, pins.D2, pins.D3, pins.D4, pins.D5, pins.D6, pins.D7,
29+
pins.D8, pins.D9, pins.D10, pins.D11, pins.D12, pins.D13,
30+
pins.D14, pins.D15];
31+
var pincount = testpins.length;
32+
var gpios = [];
33+
for (var i = 0; i < pincount; i++) {
34+
gpios[i] = gpio.open({pin: testpins[i]});
35+
}
36+
37+
var tick = 250, toggle = false;
38+
setInterval(function () {
39+
for (var i = 0; i < pincount; i++) {
40+
gpios[i].write(toggle);
41+
}
42+
toggle = !toggle;
43+
}, tick);

src/Makefile.base

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ obj-$(CONFIG_BOARD_ARDUINO_101) += \
7878
zjs_ipm.o
7979

8080
obj-$(CONFIG_BOARD_FRDM_K64F) += \
81-
zjs_k64f_pins.o
81+
zjs_k64f_pins.o \
82+
zjs_pinmux.o
8283

8384
ifeq ($(ASHELL), y)
8485
$(info Insecure Mode (development))

src/zjs_gpio.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,14 @@ static void zjs_gpio_c_callback(void *h, const void *args)
114114
// If pin.onChange exists, call it
115115
if (jerry_value_is_function(onchange_func)) {
116116
ZVAL event = jerry_create_object();
117-
uint32_t val = 0;
118-
memcpy(&val, args, 4);
117+
uint32_t *the_args = (uint32_t *)args;
119118
// Put the boolean GPIO trigger value in the object
120-
zjs_obj_add_boolean(event, val, "value");
119+
zjs_obj_add_boolean(event, the_args[0], "value");
120+
zjs_obj_add_number(event, the_args[1], "pins");
121+
// TODO: This "pins" value is pretty useless to the JS script as is,
122+
// because it is a bitmask of activated zephyr pins; need to map this
123+
// back to JS pin values somehow. So leaving undocumented for now.
124+
// This is more complex on k64f because of five GPIO ports.
121125

122126
// Call the JS callback
123127
jerry_call_function(onchange_func, ZJS_UNDEFINED, &event, 1);
@@ -138,9 +142,9 @@ static void zjs_gpio_zephyr_callback(struct device *port,
138142
gpio_pin_read(port, handle->pin, &handle->value);
139143
if ((handle->edge_both && handle->value != handle->last) ||
140144
!handle->edge_both) {
145+
uint32_t args[] = {handle->value, pins};
141146
// Signal the C callback, where we call the JS callback
142-
zjs_signal_callback(handle->callbackId, &handle->value,
143-
sizeof(handle->value));
147+
zjs_signal_callback(handle->callbackId, args, sizeof(args));
144148
handle->last = handle->value;
145149
}
146150
}

src/zjs_k64f_pins.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2016, Intel Corporation.
1+
// Copyright (c) 2016-2017, Intel Corporation.
22

33
// Zephyr includes
44
#include <zephyr.h>
@@ -52,19 +52,22 @@ jerry_value_t zjs_k64f_init()
5252
zjs_obj_add_number(obj, PTC + 16, "D0"); // verified I/O
5353
zjs_obj_add_number(obj, PTC + 17, "D1"); // verified I/O
5454
zjs_obj_add_number(obj, PTB + 9, "D2"); // verified I/O
55-
zjs_obj_add_number(obj, PTA + 1, "D3"); // I/O if preserve jtag off
55+
zjs_obj_add_number(obj, PTA + 1, "D3"); // verified I/O
5656
zjs_obj_add_number(obj, PTB + 23, "D4"); // verified I/O
57-
zjs_obj_add_number(obj, PTA + 2, "D5"); // I/O if preserve jtag off
57+
zjs_obj_add_number(obj, PTA + 2, "D5"); // verified I/O
5858
zjs_obj_add_number(obj, PTC + 2, "D6"); // verified I/O
5959
zjs_obj_add_number(obj, PTC + 3, "D7"); // verified I/O
60-
zjs_obj_add_number(obj, PTC + 12, "D8"); // PTA0 for Rev <= D (ver. I/O)
60+
61+
// currently not working on rev E3; used to work as input/output
62+
zjs_obj_add_number(obj, PTC + 12, "D8"); // PTA0 for Rev <= D
63+
6164
zjs_obj_add_number(obj, PTC + 4, "D9"); // verified I/O
6265
zjs_obj_add_number(obj, PTD + 0, "D10"); // verified I/O
6366
zjs_obj_add_number(obj, PTD + 2, "D11"); // verified I/O
6467
zjs_obj_add_number(obj, PTD + 3, "D12"); // verified I/O
6568
zjs_obj_add_number(obj, PTD + 1, "D13"); // verified I/O
66-
zjs_obj_add_number(obj, PTE + 25, "D14"); // works as input, not output
67-
zjs_obj_add_number(obj, PTE + 24, "D15"); // works as input, not output
69+
zjs_obj_add_number(obj, PTE + 25, "D14"); // verified I/O
70+
zjs_obj_add_number(obj, PTE + 24, "D15"); // verified I/O
6871

6972
// These are for onboard RGB LED
7073
zjs_obj_add_number(obj, PTB + 22, "LEDR"); // verified

src/zjs_pinmux.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright (c) 2017, Intel Corporation.
2+
3+
// This file is currently meant only for FRDM_K64F board
4+
5+
// C includes
6+
#include <stdio.h>
7+
8+
// Zephyr includes
9+
#include <kernel.h>
10+
#include <init.h>
11+
#include <pinmux.h>
12+
#include <pinmux/pinmux.h>
13+
#include <fsl_port.h>
14+
15+
// CONFIG_INIT_PINMUX_PRIORITY + 1 to override default pinmux settings
16+
#define CONFIG_K64F_PINMUX_PRIORITY 46
17+
18+
int frdm_k64f_pinmux_setup(struct device *unused)
19+
{
20+
// NOTE: Here we enable all the controllers but in a real design you would
21+
// probably try to optimize for the minimum number of GPIO controllers
22+
// turned on to save power. See zephyr/boards/arm/frdm_k64f/pinmux.c for
23+
// defaults.
24+
25+
// TODO: eventually we maybe need to analyze script to decide how to do
26+
// pinmux, or have user provide a static configuration
27+
struct device *porta = device_get_binding(CONFIG_PINMUX_MCUX_PORTA_NAME);
28+
pinmux_pin_set(porta, 0, PORT_PCR_MUX(kPORT_MuxAsGpio));
29+
pinmux_pin_set(porta, 1, PORT_PCR_MUX(kPORT_MuxAsGpio));
30+
pinmux_pin_set(porta, 2, PORT_PCR_MUX(kPORT_MuxAsGpio));
31+
32+
struct device *portb = device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME);
33+
pinmux_pin_set(portb, 9, PORT_PCR_MUX(kPORT_MuxAsGpio));
34+
pinmux_pin_set(portb, 23, PORT_PCR_MUX(kPORT_MuxAsGpio));
35+
36+
struct device *portc = device_get_binding(CONFIG_PINMUX_MCUX_PORTC_NAME);
37+
pinmux_pin_set(portc, 2, PORT_PCR_MUX(kPORT_MuxAsGpio));
38+
pinmux_pin_set(portc, 3, PORT_PCR_MUX(kPORT_MuxAsGpio));
39+
pinmux_pin_set(portc, 4, PORT_PCR_MUX(kPORT_MuxAsGpio));
40+
pinmux_pin_set(portc, 16, PORT_PCR_MUX(kPORT_MuxAsGpio));
41+
pinmux_pin_set(portc, 17, PORT_PCR_MUX(kPORT_MuxAsGpio));
42+
43+
struct device *portd = device_get_binding(CONFIG_PINMUX_MCUX_PORTD_NAME);
44+
pinmux_pin_set(portd, 0, PORT_PCR_MUX(kPORT_MuxAsGpio));
45+
pinmux_pin_set(portd, 1, PORT_PCR_MUX(kPORT_MuxAsGpio));
46+
pinmux_pin_set(portd, 2, PORT_PCR_MUX(kPORT_MuxAsGpio));
47+
pinmux_pin_set(portd, 3, PORT_PCR_MUX(kPORT_MuxAsGpio));
48+
49+
struct device *porte = device_get_binding(CONFIG_PINMUX_MCUX_PORTE_NAME);
50+
pinmux_pin_set(porte, 25, PORT_PCR_MUX(kPORT_MuxAsGpio));
51+
pinmux_pin_set(porte, 24, PORT_PCR_MUX(kPORT_MuxAsGpio));
52+
return 0;
53+
}
54+
55+
SYS_INIT(frdm_k64f_pinmux_setup, POST_KERNEL, CONFIG_K64F_PINMUX_PRIORITY);

0 commit comments

Comments
 (0)