diff options
-rw-r--r-- | include/l1ctl_proto.h | 11 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/common/l1ctl.h | 2 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/common/osmocom_data.h | 6 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/ui/ui.h | 3 | ||||
-rw-r--r-- | src/host/layer23/src/common/l1ctl.c | 36 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/app_mobile.c | 7 | ||||
-rw-r--r-- | src/host/layer23/src/ui/ui.c | 7 | ||||
-rw-r--r-- | src/target/firmware/apps/layer1/main.c | 5 | ||||
-rw-r--r-- | src/target/firmware/calypso/keypad.c | 2 | ||||
-rw-r--r-- | src/target/firmware/display/display.c | 32 | ||||
-rw-r--r-- | src/target/firmware/include/display.h | 50 | ||||
-rw-r--r-- | src/target/firmware/layer1/l23_api.c | 58 |
12 files changed, 215 insertions, 4 deletions
diff --git a/include/l1ctl_proto.h b/include/l1ctl_proto.h index 70de4bde..720a6885 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 3cf014e4..d05c64d8 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 191fb96d..b69a8267 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 75e2fad7..b2bd26f6 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 70fefec5..3804aae7 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 1473e77c..56c6b654 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 5545a5e7..5956b233 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 f122de6b..d01dbd2b 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 937f8bd8..1dc43759 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 00000000..6fe78a9f --- /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 00000000..46d8915e --- /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 230e382a..b186eac1 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; } |