summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2011-12-14 09:37:50 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2016-09-25 08:11:48 +0200
commit450a84eafc36e774045733c092a51aaa63bea862 (patch)
tree13bceb03c2ad123cc02db4c2ab9f7c445ade031a
parent39f7b1595c33b7df16294f2a97e3b6a2abbfb170 (diff)
[HACK] Use display and keypad via L1CTL
This hack is just for demonstration.
-rw-r--r--include/l1ctl_proto.h11
-rw-r--r--src/host/layer23/include/osmocom/bb/common/l1ctl.h2
-rw-r--r--src/host/layer23/include/osmocom/bb/common/osmocom_data.h6
-rw-r--r--src/host/layer23/include/osmocom/bb/ui/ui.h3
-rw-r--r--src/host/layer23/src/common/l1ctl.c36
-rw-r--r--src/host/layer23/src/mobile/app_mobile.c7
-rw-r--r--src/host/layer23/src/ui/ui.c7
-rw-r--r--src/target/firmware/apps/layer1/main.c5
-rw-r--r--src/target/firmware/calypso/keypad.c2
-rw-r--r--src/target/firmware/display/display.c32
-rw-r--r--src/target/firmware/include/display.h50
-rw-r--r--src/target/firmware/layer1/l23_api.c58
12 files changed, 215 insertions, 4 deletions
diff --git a/include/l1ctl_proto.h b/include/l1ctl_proto.h
index 70de4bd..720a688 100644
--- a/include/l1ctl_proto.h
+++ b/include/l1ctl_proto.h
@@ -57,6 +57,8 @@ enum {
L1CTL_TRAFFIC_CONF,
L1CTL_TRAFFIC_IND,
L1CTL_RINGER_REQ,
+ L1CTL_KEYPAD_IND,
+ L1CTL_DISPLAY_REQ,
};
enum ccch_mode {
@@ -311,4 +313,13 @@ struct l1ctl_ringer_req {
uint8_t volume;
} __attribute__((packed));
+struct l1ctl_keypad_ind {
+ uint8_t key;
+} __attribute__((packed));
+
+struct l1ctl_display_req {
+ uint8_t x, y;
+ char text[32];
+} __attribute__((packed));
+
#endif /* __L1CTL_PROTO_H__ */
diff --git a/src/host/layer23/include/osmocom/bb/common/l1ctl.h b/src/host/layer23/include/osmocom/bb/common/l1ctl.h
index 3cf014e..d05c64d 100644
--- a/src/host/layer23/include/osmocom/bb/common/l1ctl.h
+++ b/src/host/layer23/include/osmocom/bb/common/l1ctl.h
@@ -77,4 +77,6 @@ int l1ctl_tx_neigh_pm_req(struct osmocom_ms *ms, int num, uint16_t *arfcn);
/* Transmit L1CTL_RINGER_REQ */
int l1ctl_tx_ringer_req(struct osmocom_ms *ms, uint8_t volume);
+int l1ctl_tx_display_req(struct osmocom_ms *ms, int x, int y, char *text);
+
#endif
diff --git a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h
index 191fb96..b69a826 100644
--- a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h
+++ b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h
@@ -97,6 +97,7 @@ enum osmobb_l1ctl_sig {
S_L1CTL_TCH_MODE_CONF,
S_L1CTL_LOSS_IND,
S_L1CTL_NEIGH_PM_IND,
+ S_L1CTL_KEYPAD,
};
enum osmobb_global_sig {
@@ -134,4 +135,9 @@ struct osmobb_neigh_pm_ind {
uint8_t bsic;
};
+struct osmobb_keypad {
+ struct osmocom_ms *ms;
+ uint8_t key;
+};
+
#endif
diff --git a/src/host/layer23/include/osmocom/bb/ui/ui.h b/src/host/layer23/include/osmocom/bb/ui/ui.h
index 75e2fad..b2bd26f 100644
--- a/src/host/layer23/include/osmocom/bb/ui/ui.h
+++ b/src/host/layer23/include/osmocom/bb/ui/ui.h
@@ -3,7 +3,7 @@
#define UI_ROWS 8
#define UI_COLS 12
-#define UI_TARGET 0
+#define UI_TARGET 1
enum ui_key {
UI_KEY_0 = '0',
@@ -20,6 +20,7 @@ enum ui_key {
UI_KEY_HASH = '#',
UI_KEY_F1 = 1,
UI_KEY_F2 = 2,
+ UI_KEY_MENU = 25,
UI_KEY_PICKUP = 26,
UI_KEY_HANGUP = 27,
UI_KEY_UP = 28,
diff --git a/src/host/layer23/src/common/l1ctl.c b/src/host/layer23/src/common/l1ctl.c
index 70fefec..3804aae 100644
--- a/src/host/layer23/src/common/l1ctl.c
+++ b/src/host/layer23/src/common/l1ctl.c
@@ -950,6 +950,38 @@ int l1ctl_tx_ringer_req(struct osmocom_ms *ms, uint8_t volume)
return osmo_send_l1(ms, msg);
}
+static int rx_l1_keypad_ind(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct l1ctl_keypad_ind *kp_ind;
+ struct osmobb_keypad kp;
+
+ kp_ind = (struct l1ctl_keypad_ind *) msg->l1h;
+
+ kp.ms = ms;
+ kp.key = kp_ind->key;
+ osmo_signal_dispatch(SS_L1CTL, S_L1CTL_KEYPAD, &kp);
+
+ return 0;
+}
+
+/* Transmit L1CTL_NEIGH_PM_REQ */
+int l1ctl_tx_display_req(struct osmocom_ms *ms, int x, int y, char *text)
+{
+ struct msgb *msg;
+ struct l1ctl_display_req *dr;
+
+ msg = osmo_l1_alloc(L1CTL_DISPLAY_REQ);
+ if (!msg)
+ return -1;
+
+ dr = (struct l1ctl_display_req *) msgb_put(msg, sizeof(*dr));
+ dr->x = x;
+ dr->y = y;
+ strncpy(dr->text, text, sizeof(dr->text) - 1);
+
+ return osmo_send_l1(ms, msg);
+}
+
/* Receive incoming data from L1 using L1CTL format */
int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg)
{
@@ -1016,6 +1048,10 @@ int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg)
case L1CTL_TRAFFIC_CONF:
msgb_free(msg);
break;
+ case L1CTL_KEYPAD_IND:
+ rc = rx_l1_keypad_ind(ms, msg);
+ msgb_free(msg);
+ break;
default:
LOGP(DL1C, LOGL_ERROR, "Unknown MSG: %u\n", l1h->msg_type);
msgb_free(msg);
diff --git a/src/host/layer23/src/mobile/app_mobile.c b/src/host/layer23/src/mobile/app_mobile.c
index 1473e77..56c6b65 100644
--- a/src/host/layer23/src/mobile/app_mobile.c
+++ b/src/host/layer23/src/mobile/app_mobile.c
@@ -83,6 +83,7 @@ int mobile_signal_cb(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
struct osmocom_ms *ms;
+ struct osmobb_keypad *kp;
struct gsm_settings *set;
struct msgb *nmsg;
@@ -131,6 +132,12 @@ int mobile_signal_cb(unsigned int subsys, unsigned int signal,
}
ms->started = 1;
+ break;
+ case S_L1CTL_KEYPAD:
+ kp = signal_data;
+ ms = kp->ms;
+ ui_inst_keypad(&ms->gui.ui, kp->key);
+ break;
}
return 0;
}
diff --git a/src/host/layer23/src/ui/ui.c b/src/host/layer23/src/ui/ui.c
index 5545a5e..5956b23 100644
--- a/src/host/layer23/src/ui/ui.c
+++ b/src/host/layer23/src/ui/ui.c
@@ -25,6 +25,7 @@
#include <osmocom/core/select.h>
#include <osmocom/bb/ui/ui.h>
#include <osmocom/bb/ui/telnet_interface.h>
+#include <osmocom/bb/common/l1ctl.h>
static char *ui_center(const char *text)
{
@@ -101,6 +102,12 @@ int ui_flush(struct ui_inst *ui)
ui_telnet_puts(ui, frame);
for (i = 0; i < UI_ROWS; i++) {
sprintf(line, "|%s|\r\n", ui->buffer + (UI_COLS + 1) * i);
+ {
+ // HACK
+ struct gsm_ui *gui = container_of(ui, struct gsm_ui, ui);
+ struct osmocom_ms *ms = container_of(gui, struct osmocom_ms, gui);
+ l1ctl_tx_display_req(ms, 0, i, ui->buffer + (UI_COLS + 1) * i);
+ }
ui_telnet_puts(ui, line);
}
ui_telnet_puts(ui, frame);
diff --git a/src/target/firmware/apps/layer1/main.c b/src/target/firmware/apps/layer1/main.c
index f122de6..d01dbd2 100644
--- a/src/target/firmware/apps/layer1/main.c
+++ b/src/target/firmware/apps/layer1/main.c
@@ -140,6 +140,9 @@ static void key_handler(enum key_codes code, enum key_states state)
if (state != PRESSED)
return;
+ l1ctl_tx_keypad_ind(code);
+ return;
+
switch (code) {
case KEY_4:
tspact_toggle(6); /* TRENA (RFFE) */
@@ -169,7 +172,7 @@ static void key_handler(enum key_codes code, enum key_states state)
}
/* power down SIM, TODO: this will happen with every key pressed,
put it somewhere else ! */
- calypso_sim_powerdown();
+// calypso_sim_powerdown();
}
diff --git a/src/target/firmware/calypso/keypad.c b/src/target/firmware/calypso/keypad.c
index 937f8bd..1dc4375 100644
--- a/src/target/firmware/calypso/keypad.c
+++ b/src/target/firmware/calypso/keypad.c
@@ -43,6 +43,8 @@ static key_handler_t key_handler = NULL;
void emit_key(uint8_t key, uint8_t state)
{
+ static int power_count = 0;
+
printf("key=%u %s\n", key, state == PRESSED ? "pressed" : "released");
if(key_handler) {
diff --git a/src/target/firmware/display/display.c b/src/target/firmware/display/display.c
new file mode 100644
index 0000000..6fe78a9
--- /dev/null
+++ b/src/target/firmware/display/display.c
@@ -0,0 +1,32 @@
+
+#include <stdint.h>
+
+#include <display.h>
+
+struct display_driver *display;
+
+int display_puts(const char *str)
+{
+ char c;
+
+ if (display->puts)
+ display->puts(str);
+ else {
+ while ((c = *str++))
+ display_putchar(c);
+ }
+
+ return 0;
+}
+
+int display_goto_xy(int x, int y)
+{
+ char c;
+
+ if (display->goto_xy)
+ display->goto_xy(x, y);
+
+ return 0;
+}
+
+
diff --git a/src/target/firmware/include/display.h b/src/target/firmware/include/display.h
new file mode 100644
index 0000000..46d8915
--- /dev/null
+++ b/src/target/firmware/include/display.h
@@ -0,0 +1,50 @@
+#ifndef _DISPLAY_DRIVER_H
+#define _DISPLAY_DRIVER_H
+
+enum display_attr {
+ DISP_ATTR_INVERT = 0x0001,
+};
+
+struct display_driver {
+ char *name;
+ void (*init)(void);
+ void (*set_attr)(unsigned long attr);
+ void (*unset_attr)(unsigned long attr);
+ void (*clrscr)(void);
+ void (*goto_xy)(int xpos, int ypos);
+ void (*set_color)(int fgcolor, int bgcolor);
+ int (*putc)(unsigned char c);
+ int (*puts)(const char *str);
+};
+
+extern struct display_driver *display;
+
+static inline void display_init(void)
+{
+ display->init();
+}
+static inline void display_set_attr(unsigned long attr)
+{
+ display->set_attr(attr);
+}
+static inline void display_unset_attr(unsigned long attr)
+{
+ display->unset_attr(attr);
+}
+static inline void display_clrscr(void)
+{
+ display->clrscr();
+}
+static inline int display_putchar(unsigned char c)
+{
+ return display->putc(c);
+}
+int display_puts(const char *s);
+int display_goto_xy(int x, int y);
+
+extern const struct display_driver st7558_display;
+extern const struct display_driver ssd1783_display;
+extern const struct display_driver ssd1963_display;
+extern const struct display_driver td014_display;
+
+#endif
diff --git a/src/target/firmware/layer1/l23_api.c b/src/target/firmware/layer1/l23_api.c
index 230e382..b186eac 100644
--- a/src/target/firmware/layer1/l23_api.c
+++ b/src/target/firmware/layer1/l23_api.c
@@ -47,6 +47,9 @@
#include <calypso/sim.h>
#include <calypso/dsp.h>
#include <calypso/buzzer.h>
+#include <fb/framebuffer.h>
+#include <keypad.h>
+#include <display.h>
#include <l1ctl_proto.h>
@@ -627,6 +630,54 @@ static void l1ctl_ringer_req(struct msgb *msg)
buzzer_note(NOTE(NOTE_C, OCTAVE_4));
}
+/* Transmit a L1CTL_KEYPAD_IND */
+void l1ctl_tx_keypad_ind(uint8_t key)
+{
+ struct msgb *msg = l1ctl_msgb_alloc(L1CTL_KEYPAD_IND);
+ struct l1ctl_keypad_ind *kp_ind;
+ kp_ind = (struct l1ctl_keypad_ind *)
+ msgb_put(msg, sizeof(*kp_ind));
+
+ switch (key) {
+ case KEY_0: kp_ind->key = '0'; break;
+ case KEY_1: kp_ind->key = '1'; break;
+ case KEY_2: kp_ind->key = '2'; break;
+ case KEY_3: kp_ind->key = '3'; break;
+ case KEY_4: kp_ind->key = '4'; break;
+ case KEY_5: kp_ind->key = '5'; break;
+ case KEY_6: kp_ind->key = '6'; break;
+ case KEY_7: kp_ind->key = '7'; break;
+ case KEY_8: kp_ind->key = '8'; break;
+ case KEY_9: kp_ind->key = '9'; break;
+ case KEY_STAR: kp_ind->key = '*'; break;
+ case KEY_HASH: kp_ind->key = '#'; break;
+ case KEY_MENU: kp_ind->key = 25; break;
+ case KEY_LEFT_SB: kp_ind->key = 1; break;
+ case KEY_RIGHT_SB: kp_ind->key = 2; break;
+ case KEY_UP: kp_ind->key = 28; break;
+ case KEY_DOWN: kp_ind->key = 29; break;
+ case KEY_LEFT: kp_ind->key = 30; break;
+ case KEY_RIGHT: kp_ind->key = 31; break;
+ case KEY_OK: kp_ind->key = 26; break;
+ case KEY_POWER: kp_ind->key = 27; break;
+ case KEY_MINUS: kp_ind->key = '-'; break;
+ case KEY_PLUS: kp_ind->key = '+'; break;
+ default: kp_ind->key = 0xFF;
+ }
+
+ l1_queue_for_l2(msg);
+}
+
+static void l1ctl_display_req(struct msgb *msg)
+{
+ struct l1ctl_hdr *l1h = (struct l1ctl_hdr *) msg->data;
+ struct l1ctl_display_req *dr = (struct l1ctl_display_req *) l1h->data;
+
+ printf("DISPLAY (%d) %s\n", dr->y, dr->text);
+// display_goto_xy(dr->x, dr->y);
+ display_puts(dr->text);
+}
+
static struct llist_head l23_rx_queue = LLIST_HEAD_INIT(l23_rx_queue);
/* callback from SERCOMM when L2 sends a message to L1 */
@@ -715,11 +766,14 @@ void l1a_l23_handler(void)
l1ctl_rx_traffic_req(msg);
/* we have to keep the msgb, not free it! */
goto exit_nofree;
+ case L1CTL_RINGER_REQ:
+ l1ctl_ringer_req(msg);
+ break;
case L1CTL_SIM_REQ:
l1ctl_sim_req(msg);
break;
- case L1CTL_RINGER_REQ:
- l1ctl_ringer_req(msg);
+ case L1CTL_DISPLAY_REQ:
+ l1ctl_display_req(msg);
break;
}