1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/pkg/devices/keypad/include/keypad-event-loop.h Sat May 19 00:58:00 2018 +0200
1.3 @@ -0,0 +1,50 @@
1.4 +/*
1.5 + * Keypad event loop functionality.
1.6 + *
1.7 + * (c) 2018 Paul Boddie <paul@boddie.org.uk>
1.8 + *
1.9 + * This program is free software; you can redistribute it and/or
1.10 + * modify it under the terms of the GNU General Public License as
1.11 + * published by the Free Software Foundation; either version 2 of
1.12 + * the License, or (at your option) any later version.
1.13 + *
1.14 + * This program is distributed in the hope that it will be useful,
1.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.17 + * GNU General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License
1.20 + * along with this program; if not, write to the Free Software
1.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
1.22 + * Boston, MA 02110-1301, USA
1.23 + */
1.24 +
1.25 +#pragma once
1.26 +
1.27 +#ifdef __cplusplus
1.28 +
1.29 +#include <l4/devices/event-loop.h>
1.30 +#include <l4/util/util.h>
1.31 +
1.32 +/* Keypad event loop abstraction. */
1.33 +
1.34 +class Keypad_event_loop : public Event_handler_loop<void>
1.35 +{
1.36 +public:
1.37 + /* Initialise the event loop with a thread priority. */
1.38 +
1.39 + explicit Keypad_event_loop(int priority=0x20)
1.40 + : Event_handler_loop(priority)
1.41 + {
1.42 + }
1.43 +
1.44 + /* Event handler method. */
1.45 +
1.46 + virtual void handle()
1.47 + {
1.48 + _handler();
1.49 + l4_sleep(20); /* 20ms -> 50Hz */
1.50 + }
1.51 +};
1.52 +
1.53 +#endif
2.1 --- a/pkg/devices/keypad/src/letux400/keypad-letux400.cc Fri May 18 23:41:51 2018 +0200
2.2 +++ b/pkg/devices/keypad/src/letux400/keypad-letux400.cc Sat May 19 00:58:00 2018 +0200
2.3 @@ -24,20 +24,13 @@
2.4 #include <l4/devices/dataspace.h>
2.5 #include <l4/devices/memory.h>
2.6 #include "keypad-server.h"
2.7 +#include "keypad-event-loop.h"
2.8
2.9 -#include <l4/sys/thread.h>
2.10 -#include <pthread.h>
2.11 -#include <pthread-l4.h>
2.12 -
2.13 -#include <l4/cxx/ipc_server>
2.14 #include <l4/re/dataspace>
2.15 #include <l4/re/env>
2.16 -#include <l4/re/rm>
2.17 -#include <l4/re/util/cap_alloc>
2.18 #include <l4/re/util/object_registry>
2.19
2.20 #include <l4/sys/cache.h>
2.21 -#include <l4/util/util.h>
2.22
2.23 #include <stdint.h>
2.24
2.25 @@ -79,15 +72,26 @@
2.26
2.27 void *keymem = 0;
2.28
2.29 -/* Thread details. */
2.30 +
2.31 +
2.32 +/* Set up access to memory. */
2.33
2.34 -static pthread_t _pthread;
2.35 +static int setup_memory()
2.36 +{
2.37 + if (get_memory("jz4730-gpio", &gpio_virt_base, &gpio_virt_base_end) < 0)
2.38 + return 1;
2.39 +
2.40 + gpio_port_a = jz4730_gpio_init(gpio_virt_base, gpio_virt_base + 0x30, 32);
2.41 + gpio_port_d = jz4730_gpio_init(gpio_virt_base + 0x90, gpio_virt_base + 0xc0, 32);
2.42 +
2.43 + return 0;
2.44 +}
2.45
2.46
2.47
2.48 /* Initialise the pins for scanning the keypad. */
2.49
2.50 -static void init_keyscan(void)
2.51 +static void init_keyscan()
2.52 {
2.53 jz4730_gpio_multi_setup(gpio_port_a, &Jz4730_keypad_inputs_mask, Hw::Gpio_chip::Input, 0);
2.54 jz4730_gpio_multi_config_pull(gpio_port_a, &Jz4730_keypad_inputs_mask, Hw::Gpio_chip::Pull_up);
2.55 @@ -99,7 +103,7 @@
2.56 Store each column bitmap in the keypad array.
2.57 */
2.58
2.59 -static void scan_keypad(void)
2.60 +static void scan_keypad()
2.61 {
2.62 uint8_t column, row, value;
2.63
2.64 @@ -122,54 +126,6 @@
2.65 (unsigned long) keypad + Jz4730_keypad_gpio_outputs_count);
2.66 }
2.67
2.68 -/* Set up access to memory. */
2.69 -
2.70 -static int setup_memory(void)
2.71 -{
2.72 - if (get_memory("jz4730-gpio", &gpio_virt_base, &gpio_virt_base_end) < 0)
2.73 - return 1;
2.74 -
2.75 - gpio_port_a = jz4730_gpio_init(gpio_virt_base, gpio_virt_base + 0x30, 32);
2.76 - gpio_port_d = jz4730_gpio_init(gpio_virt_base + 0x90, gpio_virt_base + 0xc0, 32);
2.77 -
2.78 - return 0;
2.79 -}
2.80 -
2.81 -
2.82 -
2.83 -/* Worker thread for scanning the keypad. */
2.84 -
2.85 -static void *scan_thread(void *data)
2.86 -{
2.87 - (void) data;
2.88 -
2.89 - while (1)
2.90 - {
2.91 - scan_keypad();
2.92 - l4_sleep(20); /* 20ms -> 50Hz */
2.93 - }
2.94 -
2.95 - return 0;
2.96 -}
2.97 -
2.98 -/* Thread initialisation. */
2.99 -
2.100 -static int init_thread(void)
2.101 -{
2.102 - pthread_attr_t thread_attr;
2.103 - struct sched_param sp;
2.104 -
2.105 - if (pthread_attr_init(&thread_attr))
2.106 - return 1;
2.107 -
2.108 - sp.sched_priority = 0x20;
2.109 - pthread_attr_setschedpolicy(&thread_attr, SCHED_L4);
2.110 - pthread_attr_setschedparam(&thread_attr, &sp);
2.111 - pthread_attr_setinheritsched(&thread_attr, PTHREAD_EXPLICIT_SCHED);
2.112 -
2.113 - return pthread_create(&_pthread, &thread_attr, scan_thread, 0);
2.114 -}
2.115 -
2.116
2.117
2.118 static L4Re::Util::Registry_server<> server;
2.119 @@ -199,7 +155,9 @@
2.120
2.121 /* Set up a thread to scan the keypad concurrently with the server loop. */
2.122
2.123 - init_thread();
2.124 + Keypad_event_loop loop;
2.125 + loop.attach(scan_keypad);
2.126 + loop.start();
2.127
2.128 /* Initialise and register a server object. */
2.129
3.1 --- a/pkg/devices/keypad/src/qi_lb60/keypad-qi_lb60.cc Fri May 18 23:41:51 2018 +0200
3.2 +++ b/pkg/devices/keypad/src/qi_lb60/keypad-qi_lb60.cc Sat May 19 00:58:00 2018 +0200
3.3 @@ -24,17 +24,13 @@
3.4 #include <l4/devices/dataspace.h>
3.5 #include <l4/devices/memory.h>
3.6 #include "keypad-server.h"
3.7 -
3.8 -#include <l4/sys/thread.h>
3.9 -#include <pthread.h>
3.10 -#include <pthread-l4.h>
3.11 +#include "keypad-event-loop.h"
3.12
3.13 #include <l4/re/dataspace>
3.14 #include <l4/re/env>
3.15 #include <l4/re/util/object_registry>
3.16
3.17 #include <l4/sys/cache.h>
3.18 -#include <l4/util/util.h>
3.19
3.20 #include <stdint.h>
3.21
3.22 @@ -76,15 +72,26 @@
3.23
3.24 void *keymem = 0;
3.25
3.26 -/* Thread details. */
3.27 +
3.28 +
3.29 +/* Set up access to memory. */
3.30
3.31 -static pthread_t _pthread;
3.32 +static int setup_memory()
3.33 +{
3.34 + if (get_memory("jz4740-gpio", &gpio_virt_base, &gpio_virt_base_end) < 0)
3.35 + return 1;
3.36 +
3.37 + gpio_port_c = jz4740_gpio_init(gpio_virt_base + 0x200, gpio_virt_base + 0x300, 32);
3.38 + gpio_port_d = jz4740_gpio_init(gpio_virt_base + 0x300, gpio_virt_base + 0x400, 32);
3.39 +
3.40 + return 0;
3.41 +}
3.42
3.43
3.44
3.45 /* Initialise the pins for scanning the keypad. */
3.46
3.47 -static void init_keyscan(void)
3.48 +static void init_keyscan()
3.49 {
3.50 jz4740_gpio_multi_setup(gpio_port_d, &Jz4740_keypad_inputs_mask, Hw::Gpio_chip::Input, 0);
3.51 jz4740_gpio_multi_config_pull(gpio_port_d, &Jz4740_keypad_inputs_mask, Hw::Gpio_chip::Pull_up);
3.52 @@ -96,7 +103,7 @@
3.53 Store each column bitmap in the keypad array.
3.54 */
3.55
3.56 -static void scan_keypad(void)
3.57 +static void scan_keypad()
3.58 {
3.59 uint8_t column, row, value;
3.60
3.61 @@ -119,54 +126,6 @@
3.62 (unsigned long) keypad + Jz4740_keypad_gpio_outputs_count);
3.63 }
3.64
3.65 -/* Set up access to memory. */
3.66 -
3.67 -static int setup_memory(void)
3.68 -{
3.69 - if (get_memory("jz4740-gpio", &gpio_virt_base, &gpio_virt_base_end) < 0)
3.70 - return 1;
3.71 -
3.72 - gpio_port_c = jz4740_gpio_init(gpio_virt_base + 0x200, gpio_virt_base + 0x300, 32);
3.73 - gpio_port_d = jz4740_gpio_init(gpio_virt_base + 0x300, gpio_virt_base + 0x400, 32);
3.74 -
3.75 - return 0;
3.76 -}
3.77 -
3.78 -
3.79 -
3.80 -/* Worker thread for scanning the keypad. */
3.81 -
3.82 -static void *scan_thread(void *data)
3.83 -{
3.84 - (void) data;
3.85 -
3.86 - while (1)
3.87 - {
3.88 - scan_keypad();
3.89 - l4_sleep(20); /* 20ms -> 50Hz */
3.90 - }
3.91 -
3.92 - return 0;
3.93 -}
3.94 -
3.95 -/* Thread initialisation. */
3.96 -
3.97 -static int init_thread(void)
3.98 -{
3.99 - pthread_attr_t thread_attr;
3.100 - struct sched_param sp;
3.101 -
3.102 - if (pthread_attr_init(&thread_attr))
3.103 - return 1;
3.104 -
3.105 - sp.sched_priority = 0x20;
3.106 - pthread_attr_setschedpolicy(&thread_attr, SCHED_L4);
3.107 - pthread_attr_setschedparam(&thread_attr, &sp);
3.108 - pthread_attr_setinheritsched(&thread_attr, PTHREAD_EXPLICIT_SCHED);
3.109 -
3.110 - return pthread_create(&_pthread, &thread_attr, scan_thread, 0);
3.111 -}
3.112 -
3.113
3.114
3.115 static L4Re::Util::Registry_server<> server;
3.116 @@ -196,7 +155,9 @@
3.117
3.118 /* Set up a thread to scan the keypad concurrently with the server loop. */
3.119
3.120 - init_thread();
3.121 + Keypad_event_loop loop;
3.122 + loop.attach(scan_keypad);
3.123 + loop.start();
3.124
3.125 /* Initialise and register a server object. */
3.126
4.1 --- a/pkg/devices/util/include/event-loop.h Fri May 18 23:41:51 2018 +0200
4.2 +++ b/pkg/devices/util/include/event-loop.h Sat May 19 00:58:00 2018 +0200
4.3 @@ -93,4 +93,38 @@
4.4 }
4.5 };
4.6
4.7 +/* Event loop with handler and null event type. */
4.8 +
4.9 +template <>
4.10 +class Event_handler_loop<void> : public Event_loop
4.11 +{
4.12 +protected:
4.13 + /* Event type. */
4.14 +
4.15 + typedef void Event_type;
4.16 +
4.17 + /* Handler function type. */
4.18 +
4.19 + typedef void (*Event_handler)();
4.20 +
4.21 + /* External handler function. */
4.22 +
4.23 + Event_handler _handler;
4.24 +
4.25 +public:
4.26 + /* Initialise the event loop with a thread priority. */
4.27 +
4.28 + explicit Event_handler_loop(int priority=0x20)
4.29 + : Event_loop(priority)
4.30 + {
4.31 + }
4.32 +
4.33 + /* Attach a handler to the loop. */
4.34 +
4.35 + virtual void attach(Event_handler handler)
4.36 + {
4.37 + _handler = handler;
4.38 + }
4.39 +};
4.40 +
4.41 #endif