blob: d84786e18aedb45cdf13d98624aa6d5f549c9d28 [file] [log] [blame]
Harald Weltec68af6a2017-04-30 21:21:52 +02001#ifndef _SERCOMM_H
2#define _SERCOMM_H
3
4#include <osmocom/core/msgb.h>
5
6#define HDLC_FLAG 0x7E
7#define HDLC_ESCAPE 0x7D
8
9#define HDLC_C_UI 0x03
10#define HDLC_C_P_BIT (1 << 4)
11#define HDLC_C_F_BIT (1 << 4)
12
13/* a low sercomm_dlci means high priority. A high DLCI means low priority */
14enum sercomm_dlci {
15 SC_DLCI_HIGHEST = 0,
16 SC_DLCI_DEBUG = 4,
17 SC_DLCI_L1A_L23 = 5,
18 SC_DLCI_LOADER = 9,
19 SC_DLCI_CONSOLE = 10,
20 SC_DLCI_ECHO = 128,
21 _SC_DLCI_MAX
22};
23
Harald Welte13588362017-04-30 23:57:55 +020024struct osmo_sercomm_inst;
25typedef void (*dlci_cb_t)(struct osmo_sercomm_inst *sercomm, uint8_t dlci, struct msgb *msg);
Harald Weltecc95f4b2017-04-30 21:39:33 +020026
Harald Welte13588362017-04-30 23:57:55 +020027struct osmo_sercomm_inst {
Harald Weltecc95f4b2017-04-30 21:39:33 +020028 int initialized;
29 int uart_id;
30
31 /* transmit side */
32 struct {
33 struct llist_head dlci_queues[_SC_DLCI_MAX];
34 struct msgb *msg;
35 int state;
36 uint8_t *next_char;
37 } tx;
38
39 /* receive side */
40 struct {
41 dlci_cb_t dlci_handler[_SC_DLCI_MAX];
Harald Weltef6adcd72017-05-01 00:19:13 +020042 unsigned int msg_size;
Harald Weltecc95f4b2017-04-30 21:39:33 +020043 struct msgb *msg;
44 int state;
45 uint8_t dlci;
46 uint8_t ctrl;
47 } rx;
48};
49
50
Harald Weltec68af6a2017-04-30 21:21:52 +020051#ifndef HOST_BUILD
52#include <uart.h>
53/* helper functions for target */
Harald Welte13588362017-04-30 23:57:55 +020054void osmo_sercomm_bind_uart(struct osmo_sercomm_inst *sercomm, int uart);
55int osmo_sercomm_get_uart(struct osmo_sercomm_inst *sercomm);
56void osmo_sercomm_change_speed(struct osmo_sercomm_inst *sercomm, enum uart_baudrate bdrt);
Harald Weltec68af6a2017-04-30 21:21:52 +020057#endif
58
Harald Welte13588362017-04-30 23:57:55 +020059void osmo_sercomm_init(struct osmo_sercomm_inst *sercomm);
60int osmo_sercomm_initialized(struct osmo_sercomm_inst *sercomm);
Harald Weltec68af6a2017-04-30 21:21:52 +020061
62/* User Interface: Tx */
63
64/* user interface for transmitting messages for a given DLCI */
Harald Welte13588362017-04-30 23:57:55 +020065void osmo_sercomm_sendmsg(struct osmo_sercomm_inst *sercomm, uint8_t dlci, struct msgb *msg);
Harald Weltec68af6a2017-04-30 21:21:52 +020066/* how deep is the Tx queue for a given DLCI */
Harald Welte13588362017-04-30 23:57:55 +020067unsigned int osmo_sercomm_tx_queue_depth(struct osmo_sercomm_inst *sercomm, uint8_t dlci);
Harald Weltec68af6a2017-04-30 21:21:52 +020068
69/* User Interface: Rx */
70
71/* receiving messages for a given DLCI */
Harald Welte13588362017-04-30 23:57:55 +020072int osmo_sercomm_register_rx_cb(struct osmo_sercomm_inst *sercomm, uint8_t dlci, dlci_cb_t cb);
Harald Weltec68af6a2017-04-30 21:21:52 +020073
74/* Driver Interface */
75
76/* fetch one octet of to-be-transmitted serial data. returns 0 if no more data */
Harald Welte13588362017-04-30 23:57:55 +020077int osmo_sercomm_drv_pull(struct osmo_sercomm_inst *sercomm, uint8_t *ch);
Harald Weltec68af6a2017-04-30 21:21:52 +020078/* the driver has received one byte, pass it into sercomm layer.
79 returns 1 in case of success, 0 in case of unrecognized char */
Harald Welte13588362017-04-30 23:57:55 +020080int osmo_sercomm_drv_rx_char(struct osmo_sercomm_inst *sercomm, uint8_t ch);
Harald Weltec68af6a2017-04-30 21:21:52 +020081
Harald Welte13588362017-04-30 23:57:55 +020082static inline struct msgb *osmo_sercomm_alloc_msgb(unsigned int len)
Harald Weltec68af6a2017-04-30 21:21:52 +020083{
84 return msgb_alloc_headroom(len+4, 4, "sercomm_tx");
85}
86
87#endif /* _SERCOMM_H */