blob: b751bcd61c1f2a1d1ec0d4b13455d64b6b00b206 [file] [log] [blame]
#ifndef _SERCOMM_H
#define _SERCOMM_H
#include <osmocom/core/msgb.h>
#define HDLC_FLAG 0x7E
#define HDLC_ESCAPE 0x7D
#define HDLC_C_UI 0x03
#define HDLC_C_P_BIT (1 << 4)
#define HDLC_C_F_BIT (1 << 4)
/* a low sercomm_dlci means high priority. A high DLCI means low priority */
enum sercomm_dlci {
SC_DLCI_HIGHEST = 0,
SC_DLCI_DEBUG = 4,
SC_DLCI_L1A_L23 = 5,
SC_DLCI_LOADER = 9,
SC_DLCI_CONSOLE = 10,
SC_DLCI_ECHO = 128,
_SC_DLCI_MAX
};
struct sercomm_inst;
typedef void (*dlci_cb_t)(struct sercomm_inst *sercomm, uint8_t dlci, struct msgb *msg);
struct sercomm_inst {
int initialized;
int uart_id;
/* transmit side */
struct {
struct llist_head dlci_queues[_SC_DLCI_MAX];
struct msgb *msg;
int state;
uint8_t *next_char;
} tx;
/* receive side */
struct {
dlci_cb_t dlci_handler[_SC_DLCI_MAX];
struct msgb *msg;
int state;
uint8_t dlci;
uint8_t ctrl;
} rx;
};
#ifndef HOST_BUILD
#include <uart.h>
/* helper functions for target */
void sercomm_bind_uart(struct sercomm_inst *sercomm, int uart);
int sercomm_get_uart(struct sercomm_inst *sercomm);
void sercomm_change_speed(struct sercomm_inst *sercomm, enum uart_baudrate bdrt);
#endif
void sercomm_init(struct sercomm_inst *sercomm);
int sercomm_initialized(struct sercomm_inst *sercomm);
/* User Interface: Tx */
/* user interface for transmitting messages for a given DLCI */
void sercomm_sendmsg(struct sercomm_inst *sercomm, uint8_t dlci, struct msgb *msg);
/* how deep is the Tx queue for a given DLCI */
unsigned int sercomm_tx_queue_depth(struct sercomm_inst *sercomm, uint8_t dlci);
/* User Interface: Rx */
/* receiving messages for a given DLCI */
int sercomm_register_rx_cb(struct sercomm_inst *sercomm, uint8_t dlci, dlci_cb_t cb);
/* Driver Interface */
/* fetch one octet of to-be-transmitted serial data. returns 0 if no more data */
int sercomm_drv_pull(struct sercomm_inst *sercomm, uint8_t *ch);
/* the driver has received one byte, pass it into sercomm layer.
returns 1 in case of success, 0 in case of unrecognized char */
int sercomm_drv_rx_char(struct sercomm_inst *sercomm, uint8_t ch);
static inline struct msgb *sercomm_alloc_msgb(unsigned int len)
{
return msgb_alloc_headroom(len+4, 4, "sercomm_tx");
}
#endif /* _SERCOMM_H */